Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 13/13] pinctrl: mvebu: dove: reuse mpp_{set, get} in pmu callbacks
From: Sebastian Hesselbarth @ 2014-02-12 15:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392220776-30851-1-git-send-email-sebastian.hesselbarth@gmail.com>

Dove has pins that can be switched between normal and pmu functions.
Rework pmu_mpp callbacks to reuse normal mpp callbacks.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Cc: Linus Walleij <linus.walleij@linaro.org> 
Cc: Jason Cooper <jason@lakedaemon.net> 
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Gregory Clement <gregory.clement@free-electrons.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/pinctrl/mvebu/pinctrl-dove.c | 37 +++++++++++++++++-------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
index 2f384d87ea92..3e28096091b0 100644
--- a/drivers/pinctrl/mvebu/pinctrl-dove.c
+++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
@@ -82,14 +82,13 @@ static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
 	unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
 	unsigned long func;
 
-	if (pmu & (1 << pid)) {
-		func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
-		*config = (func >> shift) & MVEBU_MPP_MASK;
-		*config |= CONFIG_PMU;
-	} else {
-		func = readl(DOVE_MPP_VIRT_BASE + off);
-		*config = (func >> shift) & MVEBU_MPP_MASK;
-	}
+	if ((pmu & BIT(pid)) == 0)
+		return dove_mpp_ctrl_get(pid, config);
+
+	func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
+	*config = (func >> shift) & MVEBU_MPP_MASK;
+	*config |= CONFIG_PMU;
+
 	return 0;
 }
 
@@ -100,19 +99,17 @@ static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
 	unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
 	unsigned long func;
 
-	if (config & CONFIG_PMU) {
-		writel(pmu | (1 << pid), DOVE_PMU_MPP_GENERAL_CTRL);
-		func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
-		func &= ~(MVEBU_MPP_MASK << shift);
-		func |= (config & MVEBU_MPP_MASK) << shift;
-		writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
-	} else {
-		writel(pmu & ~(1 << pid), DOVE_PMU_MPP_GENERAL_CTRL);
-		func = readl(DOVE_MPP_VIRT_BASE + off);
-		func &= ~(MVEBU_MPP_MASK << shift);
-		func |= (config & MVEBU_MPP_MASK) << shift;
-		writel(func, DOVE_MPP_VIRT_BASE + off);
+	if ((config & CONFIG_PMU) == 0) {
+		writel(pmu & ~BIT(pid), DOVE_PMU_MPP_GENERAL_CTRL);
+		return dove_mpp_ctrl_set(pid, config);
 	}
+
+	writel(pmu | BIT(pid), DOVE_PMU_MPP_GENERAL_CTRL);
+	func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
+	func &= ~(MVEBU_MPP_MASK << shift);
+	func |= (config & MVEBU_MPP_MASK) << shift;
+	writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
+
 	return 0;
 }
 
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH 1/4] phy: miphy365x: Add Device Tree bindings for the MiPHY365x
From: Lee Jones @ 2014-02-12 16:03 UTC (permalink / raw)
  To: linux-arm-kernel

The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
devices. It has 2 ports which it can use for either; both SATA, both
PCIe or one of each in any configuration.

Cc: devicetree at vger.kernel.org
Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 .../devicetree/bindings/phy/phy-miphy365x.txt      | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-miphy365x.txt

diff --git a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
new file mode 100644
index 0000000..fdfa7ca
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
@@ -0,0 +1,43 @@
+STMicroelectronics STi MIPHY365x PHY binding
+============================================
+
+This binding describes a miphy device that is used to control PHY hardware
+for SATA and PCIe.
+
+Required properties:
+- compatible: Should be "st,miphy365x-phy"
+- #phy-cells: Should be 2 (See example)
+- reg:	      Address and length of the register set for the device
+- reg-names:  The names of the register addresses corresponding to the
+	      registers filled in "reg".
+- st,syscfg : Should be a phandle of the syscfg node.
+
+Example:
+
+	miphy365x_phy: miphy365x at 0 {
+		compatible = "st,miphy365x-phy";
+		#phy-cells = <1>;
+		reg =	<0xfe382000 0x100>,
+			<0xfe38a000 0x100>,
+			<0xfe394000 0x100>,
+			<0xfe804000 0x100>;
+		reg-names = "sata0", "sata1", "pcie0", "pcie1";
+		st,syscfg= <&syscfg_rear>;
+	};
+
+Specifying phy control of devices
+=================================
+
+Device nodes should specify the configuration required in their "phys"
+property, containing a phandle to the miphy device node, a port number
+and a device type.
+
+Example:
+
+#include <dt-bindings/phy/phy-miphy365x.h>
+
+	sata0: sata at fe380000 {
+		...
+		phys	  = <&miphy365x_phy MIPHY_PORT_0 MIPHY_TYPE_SATA>;
+		...
+	};
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 2/4] phy: miphy365x: Add MiPHY365x header file for DT x Driver defines
From: Lee Jones @ 2014-02-12 16:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392220985-28189-1-git-send-email-lee.jones@linaro.org>

This provides the shared header file which will be reference from both
the MiPHY365x driver and its associated Device Tree node(s).

Cc: devicetree at vger.kernel.org
Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 include/dt-bindings/phy/phy-miphy365x.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 include/dt-bindings/phy/phy-miphy365x.h

diff --git a/include/dt-bindings/phy/phy-miphy365x.h b/include/dt-bindings/phy/phy-miphy365x.h
new file mode 100644
index 0000000..8757c02
--- /dev/null
+++ b/include/dt-bindings/phy/phy-miphy365x.h
@@ -0,0 +1,25 @@
+/*
+ * This header provides constants for the phy framework
+ * based on the STMicroelectronics miphy365x.
+ */
+#ifndef _DT_BINDINGS_PHY_MIPHY
+#define _DT_BINDINGS_PHY_MIPHY
+
+/* Supports 16 ports without a datatype change (u8 & 0xF0). */
+#define MIPHY_PORT_0			0
+#define MIPHY_PORT_1			1
+#define MIPHY_PORT_2			2
+#define MIPHY_PORT_3			3
+
+/* Supports 16 types without a datatype change (u8 & 0x0F). */
+#define MIPHY_TYPE_SHIFT		4
+#define MIPHY_TYPE_SATA			(0 << MIPHY_TYPE_SHIFT)
+#define MIPHY_TYPE_PCIE			(1 << MIPHY_TYPE_SHIFT)
+#define MIPHY_TYPE_USB			(2 << MIPHY_TYPE_SHIFT)
+
+#define MIPHY_SATA_PORT0		(MIPHY_TYPE_SATA) | (MIPHY_PORT_0)
+#define MIPHY_SATA_PORT1		(MIPHY_TYPE_SATA) | (MIPHY_PORT_1)
+#define MIPHY_PCIE_PORT0		(MIPHY_TYPE_PCIE) | (MIPHY_PORT_0)
+#define MIPHY_PCIE_PORT1		(MIPHY_TYPE_PCIE) | (MIPHY_PORT_1)
+
+#endif /* _DT_BINDINGS_PHY_MIPHY */
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 3/4] ARM: DT: STi: Add DT node for MiPHY365x
From: Lee Jones @ 2014-02-12 16:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392220985-28189-1-git-send-email-lee.jones@linaro.org>

The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
devices. It has 2 ports which it can use for either; both SATA, both
PCIe or one of each in any configuration.

Cc: devicetree at vger.kernel.org
Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/boot/dts/stih416-b2020-revE.dts |  6 +++++-
 arch/arm/boot/dts/stih416-b2020.dts      |  6 ++++++
 arch/arm/boot/dts/stih416.dtsi           | 13 +++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stih416-b2020-revE.dts b/arch/arm/boot/dts/stih416-b2020-revE.dts
index a874570..dbe67fa 100644
--- a/arch/arm/boot/dts/stih416-b2020-revE.dts
+++ b/arch/arm/boot/dts/stih416-b2020-revE.dts
@@ -32,6 +32,10 @@
 		ethernet1: ethernet at fef08000 {
 			snps,reset-gpio 	= <&PIO0 7>;
 		};
-	};
 
+		miphy365x_phy: miphy365x at 0 {
+			st,pcie_tx_pol_inv = <1>;
+			st,sata_gen = "gen3";
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/stih416-b2020.dts b/arch/arm/boot/dts/stih416-b2020.dts
index 276f28d..fd9cbad 100644
--- a/arch/arm/boot/dts/stih416-b2020.dts
+++ b/arch/arm/boot/dts/stih416-b2020.dts
@@ -13,4 +13,10 @@
 	model = "STiH416 B2020";
 	compatible = "st,stih416", "st,stih416-b2020";
 
+	soc {
+		miphy365x_phy: miphy365x at 0 {
+			st,pcie_tx_pol_inv = <1>;
+			st,sata_gen = "gen3";
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
index 85b8063..9fd8efb 100644
--- a/arch/arm/boot/dts/stih416.dtsi
+++ b/arch/arm/boot/dts/stih416.dtsi
@@ -9,6 +9,8 @@
 #include "stih41x.dtsi"
 #include "stih416-clock.dtsi"
 #include "stih416-pinctrl.dtsi"
+
+#include <dt-bindings/phy/phy-miphy365x.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset-controller/stih416-resets.h>
 / {
@@ -140,5 +142,16 @@
 			clocks		= <&CLK_S_ICN_REG_0>;
 		};
 
+		miphy365x_phy: miphy365x at 0 {
+			compatible      = "st,miphy365x-phy";
+			reg        	= <0xfe382000 0x100>,
+					  <0xfe38a000 0x100>,
+					  <0xfe394000 0x100>,
+					  <0xfe804000 0x100>;
+			reg-names  	= "sata0", "sata1", "pcie0", "pcie1";
+
+			#phy-cells 	= <2>;
+			st,syscfg  	= <&syscfg_rear>;
+		};
 	};
 };
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 4/4] phy: miphy365x: Provide support for the MiPHY356x Generic PHY
From: Lee Jones @ 2014-02-12 16:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392220985-28189-1-git-send-email-lee.jones@linaro.org>

The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
devices. It has 2 ports which it can use for either; both SATA, both
PCIe or one of each in any configuration.

Cc: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/phy/Kconfig         |   8 +
 drivers/phy/Makefile        |   1 +
 drivers/phy/phy-miphy365x.c | 634 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 643 insertions(+)
 create mode 100644 drivers/phy/phy-miphy365x.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 330ef2d..bb2706a 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -21,6 +21,14 @@ config PHY_EXYNOS_MIPI_VIDEO
 	  Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
 	  and EXYNOS SoCs.
 
+config PHY_MIPHY365X
+	tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
+	depends on ARCH_STI
+	depends on GENERIC_PHY
+	help
+	  Enable this to support the miphy transceiver (for SATA/PCIE)
+	  that is part of STMicroelectronics STiH41x SoC series.
+
 config OMAP_USB2
 	tristate "OMAP USB2 PHY Driver"
 	depends on ARCH_OMAP2PLUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d0caae9..5879639 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -5,5 +5,6 @@
 obj-$(CONFIG_GENERIC_PHY)		+= phy-core.o
 obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)	+= phy-exynos-dp-video.o
 obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
+obj-$(CONFIG_PHY_MIPHY365X)		+= phy-miphy365x.o
 obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
new file mode 100644
index 0000000..c4124e3
--- /dev/null
+++ b/drivers/phy/phy-miphy365x.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics
+ *
+ * STMicroelectronics PHY driver MiPHY365 (for SoC STiH416).
+ *
+ * Author: Alexandre Torgue <alexandre.torgue@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/platform_device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/phy/phy.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/phy/phy-miphy365x.h>
+
+#define HFC_TIMEOUT		50
+
+#define SYSCFG_2521		0x824
+#define SYSCFG_2522		0x828
+#define SYSCFG_PCIE_SATA_MASK	BIT(1)
+#define SYSCFG_PCIE_SATA_POS	1
+
+/* MiPHY365x register definitiona */
+#define RESET_REG		0x00
+#define RST_PLL			BIT(1)
+#define RST_PLL_CAL		BIT(2)
+#define RST_RX			BIT(4)
+#define RST_MACRO		BIT(7)
+
+#define STATUS_REG		0x01
+#define IDLL_RDY		BIT(0)
+#define PLL_RDY			BIT(1)
+#define DES_BIT_LOCK		BIT(2)
+#define DES_SYMBOL_LOCK		BIT(3)
+
+#define CTRL_REG		0x02
+#define TERM_EN			BIT(0)
+#define PCI_EN			BIT(2)
+#define DES_BIT_LOCK_EN		BIT(3)
+#define TX_POL			BIT(5)
+
+#define INT_CTRL_REG		0x03
+
+#define BOUNDARY1_REG		0x10
+#define SPDSEL_SEL		BIT(0)
+
+#define BOUNDARY3_REG		0x12
+#define TX_SPDSEL_GEN1_VAL	0
+#define TX_SPDSEL_GEN2_VAL	0x01
+#define TX_SPDSEL_GEN3_VAL	0x02
+#define RX_SPDSEL_GEN1_VAL	0
+#define RX_SPDSEL_GEN2_VAL	(0x01 << 3)
+#define RX_SPDSEL_GEN3_VAL	(0x02 << 3)
+
+#define PCIE_REG		0x16
+
+#define BUF_SEL_REG		0x20
+#define CONF_GEN_SEL_GEN3	0x02
+#define CONF_GEN_SEL_GEN2	0x01
+#define PD_VDDTFILTER		BIT(4)
+
+#define TXBUF1_REG		0x21
+#define SWING_VAL		0x04
+#define SWING_VAL_GEN1		0x03
+#define PREEMPH_VAL		(0x3 << 5)
+
+#define TXBUF2_REG		0x22
+#define TXSLEW_VAL		0x2
+#define TXSLEW_VAL_GEN1		0x4
+
+#define RXBUF_OFFSET_CTRL_REG	0x23
+
+#define RXBUF_REG		0x25
+#define SDTHRES_VAL		0x01
+#define EQ_ON3			(0x03 << 4)
+#define EQ_ON1			(0x01 << 4)
+
+#define COMP_CTRL1_REG		0x40
+#define START_COMSR		BIT(0)
+#define START_COMZC		BIT(1)
+#define COMP_AUTO_LOAD		BIT(4)
+
+#define COMP_CTRL2_REG		0x41
+#define COMP_2MHZ_RAT_GEN1	0x1e
+#define COMP_2MHZ_RAT		0xf
+
+#define COMP_CTRL3_REG		0x42
+#define COMSR_COMP_REF		0x33
+
+#define COMP_IDLL_REG		0x47
+#define COMZC_IDLL		0x2a
+
+#define PLL_CTRL1_REG		0x50
+#define PLL_START_CAL		BIT(0)
+#define BUF_EN			BIT(2)
+#define SYNCHRO_TX		BIT(3)
+#define SSC_EN			BIT(6)
+#define CONFIG_PLL		BIT(7)
+
+#define PLL_CTRL2_REG		0x51
+#define BYPASS_PLL_CAL		BIT(1)
+
+#define PLL_RAT_REG		0x52
+
+#define PLL_SSC_STEP_MSB_REG	0x56
+#define PLL_SSC_STEP_MSB_VAL	0x03
+
+#define PLL_SSC_STEP_LSB_REG	0x57
+#define PLL_SSC_STEP_LSB_VAL	0x63
+
+#define PLL_SSC_PER_MSB_REG	0x58
+#define PLL_SSC_PER_MSB_VAL	0
+
+#define PLL_SSC_PER_LSB_REG	0x59
+#define PLL_SSC_PER_LSB_VAL	0xf1
+
+#define IDLL_TEST_REG		0x72
+#define START_CLK_HF		BIT(6)
+
+#define DES_BITLOCK_REG		0x86
+#define BIT_LOCK_LEVEL		0x01
+#define BIT_LOCK_CNT_512	(0x03 << 5)
+
+static u8 ports[] = { MIPHY_PORT_0, MIPHY_PORT_1 };
+
+struct miphy365x_phy {
+	struct phy *phy;
+	void __iomem *base;
+	void __iomem *sata;
+	void __iomem *pcie;
+	u8 type;
+	u8 port;
+};
+
+struct miphy365x_dev {
+	struct device *dev;
+	struct mutex miphy_mutex;
+	struct miphy365x_phy phys[ARRAY_SIZE(ports)];
+	bool pcie_tx_pol_inv;
+	bool sata_tx_pol_inv;
+	u32 sata_gen;
+	struct regmap *regmap;
+};
+
+enum miphy_sata_gen {
+	SATA_GEN1,
+	SATA_GEN2,
+	SATA_GEN3
+};
+
+static u8 rx_tx_spd[] = {
+	TX_SPDSEL_GEN1_VAL | RX_SPDSEL_GEN1_VAL,
+	TX_SPDSEL_GEN2_VAL | RX_SPDSEL_GEN2_VAL,
+	TX_SPDSEL_GEN3_VAL | RX_SPDSEL_GEN3_VAL
+};
+
+#define miphy365x_phy_to_dev(inst) \
+	container_of((inst), struct miphy365x_dev, phys[(inst)->port]);
+
+/*
+ * This function selects the system configuration,
+ * either two SATA, one SATA and one PCIe, or two PCIe lanes.
+ */
+static int miphy365x_set_path(struct miphy365x_phy *miphy_phy,
+			      struct miphy365x_dev *miphy_dev)
+{
+	u8 config = miphy_phy->type | miphy_phy->port;
+	u32 mask  = SYSCFG_PCIE_SATA_MASK;
+	u32 reg;
+	bool sata;
+
+	switch (config) {
+	case MIPHY_SATA_PORT0:
+		reg = SYSCFG_2521;
+		sata = true;
+		break;
+	case MIPHY_PCIE_PORT1:
+		reg = SYSCFG_2522;
+		sata = false;
+		break;
+	default:
+		dev_err(miphy_dev->dev, "Configuration not supported\n");
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(miphy_dev->regmap, reg, mask,
+				  sata << SYSCFG_PCIE_SATA_POS);
+}
+
+static void miphy365x_phy_init_pcie_port(struct miphy365x_phy *miphy_phy,
+					 struct miphy365x_dev *miphy_dev)
+{
+	u8 val;
+
+	if (!miphy_dev->pcie_tx_pol_inv)
+		return;
+
+	/* Invert Tx polarity and clear pci_txdetect_pol bit */
+	val = TERM_EN | PCI_EN | DES_BIT_LOCK_EN | TX_POL;
+	writeb_relaxed(val, miphy_phy->base + CTRL_REG);
+	writeb_relaxed(0x00, miphy_phy->base + PCIE_REG);
+}
+
+static inline int miphy365x_phy_hfc_not_rdy(struct miphy365x_phy *miphy_phy,
+					    struct miphy365x_dev *miphy_dev)
+{
+	int timeout = HFC_TIMEOUT;
+	u8 mask = IDLL_RDY | PLL_RDY;
+	u8 regval;
+
+	do {
+		regval = readb_relaxed(miphy_phy->base + STATUS_REG);
+		usleep_range(2000, 2500);
+	} while (timeout-- && (regval & mask));
+
+	if (timeout < 0) {
+		dev_err(miphy_dev->dev, "HFC ready timeout!\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static inline int miphy365x_phy_rdy(struct miphy365x_phy *miphy_phy,
+				    struct miphy365x_dev *miphy_dev)
+{
+	int timeout = HFC_TIMEOUT;
+	u8 mask = mask = IDLL_RDY | PLL_RDY;
+	u8 regval;
+
+	do {
+		regval = readb_relaxed(miphy_phy->base + STATUS_REG);
+		usleep_range(2000, 2500);
+	} while (timeout-- && ((regval & mask) != mask));
+
+	if (timeout < 0) {
+		dev_err(miphy_dev->dev, "PHY not ready timeout!\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static inline void miphy365x_phy_set_comp(struct miphy365x_phy *miphy_phy,
+					  struct miphy365x_dev *miphy_dev)
+{
+	u8 val, mask;
+
+	if (miphy_dev->sata_gen == SATA_GEN1)
+		writeb_relaxed(COMP_2MHZ_RAT_GEN1,
+			       miphy_phy->base + COMP_CTRL2_REG);
+	else
+		writeb_relaxed(COMP_2MHZ_RAT,
+			       miphy_phy->base + COMP_CTRL2_REG);
+
+	if (miphy_dev->sata_gen != SATA_GEN3) {
+		writeb_relaxed(COMSR_COMP_REF,
+			       miphy_phy->base + COMP_CTRL3_REG);
+		/*
+		 * Force VCO current to value defined by address 0x5A
+		 * and disable PCIe100Mref bit
+		 * Enable auto load compensation for pll_i_bias
+		 */
+		writeb_relaxed(BYPASS_PLL_CAL, miphy_phy->base + PLL_CTRL2_REG);
+		writeb_relaxed(COMZC_IDLL, miphy_phy->base + COMP_IDLL_REG);
+	}
+
+	/*
+	 * Force restart compensation and enable auto load
+	 * for Comzc_Tx, Comzc_Rx and Comsr on macro
+	 */
+	val = START_COMSR | START_COMZC | COMP_AUTO_LOAD;
+	writeb_relaxed(val, miphy_phy->base + COMP_CTRL1_REG);
+
+	mask = DES_BIT_LOCK | DES_SYMBOL_LOCK;
+	while ((readb_relaxed(miphy_phy->base + COMP_CTRL1_REG) & mask)	!= mask)
+		cpu_relax();
+}
+
+static inline void miphy365x_phy_set_ssc(struct miphy365x_phy *miphy_phy,
+					 struct miphy365x_dev *miphy_dev)
+{
+	u8 val;
+
+	/*
+	 * SSC Settings. SSC will be enabled through Link
+	 * SSC Ampl. = 0.4%
+	 * SSC Freq = 31KHz
+	 */
+	writeb_relaxed(PLL_SSC_STEP_MSB_VAL,
+			miphy_phy->base + PLL_SSC_STEP_MSB_REG);
+	writeb_relaxed(PLL_SSC_STEP_LSB_VAL,
+			miphy_phy->base + PLL_SSC_STEP_LSB_REG);
+	writeb_relaxed(PLL_SSC_PER_MSB_VAL,
+			miphy_phy->base + PLL_SSC_PER_MSB_REG);
+	writeb_relaxed(PLL_SSC_PER_LSB_VAL,
+			miphy_phy->base + PLL_SSC_PER_LSB_REG);
+
+	/* SSC Settings complete */
+	if (miphy_dev->sata_gen == SATA_GEN1) {
+		val = PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
+		writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
+	} else {
+		val = SSC_EN | PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
+		writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
+	}
+}
+
+static int miphy365x_phy_init_sata_port(struct miphy365x_phy *miphy_phy,
+					struct miphy365x_dev *miphy_dev)
+{
+	int ret;
+	u8 val;
+
+	/*
+	 * Force PHY macro reset, PLL calibration reset, PLL reset
+	 * and assert Deserializer Reset
+	 */
+	val = RST_PLL | RST_PLL_CAL | RST_RX | RST_MACRO;
+	writeb_relaxed(val, miphy_phy->base + RESET_REG);
+
+	if (miphy_dev->sata_tx_pol_inv)
+		writeb_relaxed(TX_POL, miphy_phy->base + CTRL_REG);
+
+	/*
+	 * Force macro1 to use rx_lspd, tx_lspd
+	 * Force Rx_Clock on first I-DLL phase
+	 * Force Des in HP mode on macro, rx_lspd, tx_lspd for Gen2/3
+	 */
+	writeb_relaxed(SPDSEL_SEL, miphy_phy->base + BOUNDARY1_REG);
+	writeb_relaxed(START_CLK_HF, miphy_phy->base + IDLL_TEST_REG);
+	val = rx_tx_spd[miphy_dev->sata_gen];
+	writeb_relaxed(val, miphy_phy->base + BOUNDARY3_REG);
+
+	/* Wait for HFC_READY = 0 */
+	ret = miphy365x_phy_hfc_not_rdy(miphy_phy, miphy_dev);
+	if (ret)
+		return ret;
+
+	/* Compensation Recalibration */
+	miphy365x_phy_set_comp(miphy_phy, miphy_dev);
+
+	switch (miphy_dev->sata_gen) {
+	case SATA_GEN3:
+		/*
+		 * TX Swing target 550-600mv peak to peak diff
+		 * Tx Slew target 90-110ps rising/falling time
+		 * Rx Eq ON3, Sigdet threshold SDTH1
+		 */
+		val = PD_VDDTFILTER | CONF_GEN_SEL_GEN3;
+		writeb_relaxed(val, miphy_phy->base + BUF_SEL_REG);
+		val = SWING_VAL | PREEMPH_VAL;
+		writeb_relaxed(val, miphy_phy->base + TXBUF1_REG);
+		writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG);
+		writeb_relaxed(0x00, miphy_phy->base + RXBUF_OFFSET_CTRL_REG);
+		val = SDTHRES_VAL | EQ_ON3;
+		writeb_relaxed(val, miphy_phy->base + RXBUF_REG);
+		break;
+	case SATA_GEN2:
+		/*
+		 * conf gen sel=0x1 to program Gen2 banked registers
+		 * VDDT filter ON
+		 * Tx Swing target 550-600mV peak-to-peak diff
+		 * Tx Slew target 90-110 ps rising/falling time
+		 * RX Equalization ON1, Sigdet threshold SDTH1
+		 */
+		writeb_relaxed(CONF_GEN_SEL_GEN2,
+			       miphy_phy->base + BUF_SEL_REG);
+		writeb_relaxed(SWING_VAL, miphy_phy->base + TXBUF1_REG);
+		writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG);
+		val = SDTHRES_VAL | EQ_ON1;
+		writeb_relaxed(val, miphy_phy->base + RXBUF_REG);
+		break;
+	case SATA_GEN1:
+		/*
+		 * conf gen sel = 00b to program Gen1 banked registers
+		 * VDDT filter ON
+		 * Tx Swing target 500-550mV peak-to-peak diff
+		 * Tx Slew target120-140 ps rising/falling time
+		 */
+		writeb_relaxed(PD_VDDTFILTER, miphy_phy->base + BUF_SEL_REG);
+		writeb_relaxed(SWING_VAL_GEN1, miphy_phy->base + TXBUF1_REG);
+		writeb_relaxed(TXSLEW_VAL_GEN1,	miphy_phy->base + TXBUF2_REG);
+		break;
+	default:
+		break;
+	}
+
+	/* Force Macro1 in partial mode & release pll cal reset */
+	writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
+	usleep_range(100, 150);
+
+	miphy365x_phy_set_ssc(miphy_phy, miphy_dev);
+
+	/* Wait for phy_ready */
+	ret = miphy365x_phy_rdy(miphy_phy, miphy_dev);
+	if (ret)
+		return ret;
+
+	/*
+	 * Enable macro1 to use rx_lspd & tx_lspd
+	 * Release Rx_Clock on first I-DLL phase on macro1
+	 * Assert deserializer reset
+	 * des_bit_lock_en is set
+	 * bit lock detection strength
+	 * Deassert deserializer reset
+	 */
+	writeb_relaxed(0x00, miphy_phy->base + BOUNDARY1_REG);
+	writeb_relaxed(0x00, miphy_phy->base + IDLL_TEST_REG);
+	writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
+	val = miphy_dev->sata_tx_pol_inv ?
+		(TX_POL | DES_BIT_LOCK_EN) : DES_BIT_LOCK_EN;
+	writeb_relaxed(val, miphy_phy->base + CTRL_REG);
+
+	val = BIT_LOCK_CNT_512 | BIT_LOCK_LEVEL;
+	writeb_relaxed(val, miphy_phy->base + DES_BITLOCK_REG);
+	writeb_relaxed(0x00, miphy_phy->base + RESET_REG);
+
+	return 0;
+}
+
+static int miphy365x_phy_init(struct phy *phy)
+{
+	int ret = 0;
+	struct miphy365x_phy *miphy_phy = phy_get_drvdata(phy);
+	struct miphy365x_dev *miphy_dev = miphy365x_phy_to_dev(miphy_phy);
+
+	mutex_lock(&miphy_dev->miphy_mutex);
+
+	ret = miphy365x_set_path(miphy_phy, miphy_dev);
+	if (ret) {
+		mutex_unlock(&miphy_dev->miphy_mutex);
+		return ret;
+	}
+
+	/* Initialise Miphy for PCIe or SATA */
+	if (miphy_phy->type == MIPHY_TYPE_PCIE)
+		miphy365x_phy_init_pcie_port(miphy_phy, miphy_dev);
+	else
+		ret = miphy365x_phy_init_sata_port(miphy_phy, miphy_dev);
+
+	mutex_unlock(&miphy_dev->miphy_mutex);
+
+	return ret;
+}
+
+static int miphy365x_phy_power_on(struct phy *phy)
+{
+	return 0;
+}
+
+static int miphy365x_phy_power_off(struct phy *phy)
+{
+	return 0;
+}
+
+static struct phy *miphy365x_phy_xlate(struct device *dev,
+				       struct of_phandle_args *args)
+{
+	struct miphy365x_dev *state = dev_get_drvdata(dev);
+	u8 port = args->args[0];
+	u8 type = args->args[1];
+
+	if (WARN_ON(port >= ARRAY_SIZE(ports)))
+		return ERR_PTR(-EINVAL);
+
+	if (type == MIPHY_TYPE_SATA)
+		state->phys[port].base = state->phys[port].sata;
+	else if (type == MIPHY_TYPE_PCIE)
+		state->phys[port].base = state->phys[port].pcie;
+	else {
+		WARN(1, "Invalid type specified in DT");
+		return ERR_PTR(-EINVAL);
+	}
+
+	state->phys[port].type = type;
+
+	return state->phys[port].phy;
+}
+
+static struct phy_ops miphy365x_phy_ops = {
+	.init		= miphy365x_phy_init,
+	.power_on	= miphy365x_phy_power_on,
+	.power_off	= miphy365x_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int miphy365x_phy_get_base_addr(struct platform_device *pdev,
+				       struct miphy365x_phy *phy, u8 port)
+{
+	struct resource *res;
+	char sata[16];
+	char pcie[16];
+
+	sprintf(sata, "sata%d", port);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, sata);
+	if (!res)
+		return -ENODEV;
+
+	phy->sata = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!phy->sata)
+		return -ENOMEM;
+
+	sprintf(pcie, "pcie%d", port);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pcie);
+	if (!res)
+		return -ENODEV;
+
+	phy->pcie = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!phy->pcie)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int miphy365x_phy_of_probe(struct device_node *np,
+				  struct miphy365x_dev *phy_dev)
+{
+	const char *sata_gen;
+
+	phy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (IS_ERR(phy_dev->regmap)) {
+		dev_err(phy_dev->dev, "No syscfg phandle specified\n");
+		return PTR_ERR(phy_dev->regmap);
+	}
+
+	/* Default */
+	phy_dev->sata_gen = SATA_GEN1;
+
+	of_property_read_string(np, "st,sata_gen", &sata_gen);
+	if (sata_gen) {
+		if (!strcmp(sata_gen, "gen3"))
+			phy_dev->sata_gen = SATA_GEN3;
+		else if (!strcmp(sata_gen, "gen2"))
+			phy_dev->sata_gen = SATA_GEN2;
+	}
+
+	phy_dev->pcie_tx_pol_inv =
+		of_property_read_bool(np, "st,pcie_tx_pol_inv");
+
+	phy_dev->sata_tx_pol_inv =
+		of_property_read_bool(np, "st,sata_tx_pol_inv");
+
+	return 0;
+}
+
+static int miphy365x_phy_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct miphy365x_dev *phy_dev;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *provider;
+	u8 port;
+	int ret;
+
+	if (!np) {
+		dev_err(dev, "No DT found\n");
+		return -EINVAL;
+	}
+
+	phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL);
+	if (!phy_dev)
+		return -ENOMEM;
+
+	ret = miphy365x_phy_of_probe(np, phy_dev);
+	if (ret)
+		return ret;
+
+	phy_dev->dev = dev;
+
+	dev_set_drvdata(dev, phy_dev);
+
+	mutex_init(&phy_dev->miphy_mutex);
+
+	provider = devm_of_phy_provider_register(dev, miphy365x_phy_xlate);
+	if (IS_ERR(provider))
+		return PTR_ERR(provider);
+
+	for (port = 0; port < ARRAY_SIZE(ports); port++) {
+		struct phy *phy;
+
+		phy = devm_phy_create(dev, &miphy365x_phy_ops, NULL);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create PHY on port %d\n", port);
+			return PTR_ERR(phy);
+		}
+
+		phy_dev->phys[port].phy  = phy;
+		phy_dev->phys[port].port = port;
+
+		ret = miphy365x_phy_get_base_addr(pdev,
+					&phy_dev->phys[port], port);
+		if (ret)
+			return ret;
+
+		phy_set_drvdata(phy, &phy_dev->phys[port]);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id miphy365x_phy_of_match[] = {
+	{ .compatible = "st,miphy365x-phy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, miphy365x_phy_of_match);
+
+static struct platform_driver miphy365x_phy_driver = {
+	.probe	= miphy365x_phy_probe,
+	.driver = {
+		.name	= "miphy365x-phy",
+		.owner	= THIS_MODULE,
+		.of_match_table	= miphy365x_phy_of_match,
+	}
+};
+module_platform_driver(miphy365x_phy_driver);
+
+MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics miphy365x driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 14/28] Remove MACH_SMDKC210
From: Mark Brown @ 2014-02-12 16:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392070159.27939.34.camel@x220>

On Mon, Feb 10, 2014 at 11:09:19PM +0100, Paul Bolle wrote:

> See, if you scan v3.10:arch/arm/mach-exynos/mach-smdkv310.c you'll
> notice the string "smdk-audio". If you grep that string you get a few
> hits. But none in v3.10:sound/soc/samsung/smdk_wm9713.c. And if you scan
> v3.10:sound/soc/samsung/smdk_wm9713.c for strings you'll find stuff like
> "wm9713-hifi",  "wm9713-codec", and "soc-audio". But these don't show up
> in v3.10:arch/arm/mach-exynos/mach-smdkv310.c. So it's not obvious how
> these two files relate.

> And I'm left wondering why SND_SOC_SAMSUNG_SMDK_WM9713 actually depends
> on (among other symbols) MACH_SMDKV310 and MACH_SMDKC210 in v3.10.

The hardware is physically present on those boards but must be selected
with DIP switches, the device registration needs to be changed in the
kernel when that happens (as the DT must be when it is in use).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140212/33499d57/attachment.sig>

^ permalink raw reply

* [PATCH 4/7] spi: pl022: attempt to get sspclk by name
From: Mark Rutland @ 2014-02-12 16:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1786282.mNUF0ZaUg2@wuerfel>

On Wed, Feb 12, 2014 at 01:03:26PM +0000, Arnd Bergmann wrote:
> On Wednesday 12 February 2014 11:47:40 Mark Rutland wrote:
> > On Wed, Feb 12, 2014 at 11:21:50AM +0000, Arnd Bergmann wrote:
> > > On Wednesday 12 February 2014, Mark Rutland wrote:
> > > > To me it feels odd to require the last clock in the list (apb_pclk) to
> > > > be named, and the rest to be in a particular order. For the dt case it
> > > > seems saner to add new clocks with names as it allows arbitrary subsets
> > > > of clocks to be wired up and described (though obviously in this case a
> > > > missing sspclk would be problematic).
> > > 
> > > Yes, good point about the missing clocks, and I also agree mixing ordered
> > > and named clocks in one device is rather odd and can lead to trouble.
> > > 
> > > I guess there isn't really a good way out here, and I certainly won't
> > > ask for it to be done one way or the other if someone else has a 
> > > good argument which way it should be implemented.
> > 
> > Having thought about it, all dts that for the ssp_pclk must have some
> > name for the sspclk (though the specific name is arbitrary). I could get
> > the driver to try each of those before falling back to the index
> > (perhaps with a helper that takes a list of known aliases), so all
> > existing dts (that we are aware of) would work with the clock requested
> > by name.
> 
> Strange. Why do the even have names in there? What are those strings?

I guess they're there as spacers to allow the AMBA bus code to get the
right clock when it calls clk_get(&pcdev->dev, "apb_pclk").  Everyone
seems to have worked around the binding rather than reporting the issue
or fixing it.

>From a quick grep, for pl022's SSPCLK we currently have the strings:

* ssp{0,1}clk
* spi_clk
* spi{0,1,2,3}clk

Though I may have missed a string or two where nodes get amended in more
specific files. A grep for apb_clk to find neighbours didn't highlight
any obvious ones.

> 
> I noticed that ux500 has uses four different strings, one for each
> instance, which is obviously a bug and should just be fixed. There is
> no way this was intentional, and we can just rely on teh fallback
> if you want to have that anyway.

Sure, I'll fix those up once we have a preferred name. I guess this
would be SSPCLK by Russell's comments, I wasn't able to find a prior use
in the git history, but it would be in keeping with KMIREFCLK as used by
the pl050 driver.

Given the general policy of trying to not break support for existing
DTBs we'll need some fallback, either using the first clock or getting
the driver to try the names above.

> 
> > I assume that for the non-dt case it's possible to name clock inputs to
> > a device without the clock being associated with the name globally? If
> > so we could get rid of the index usage entirely in this case.
> 
> Sorry, I don't understand the question.

I thought one of the issues before dt was that clocks were in a global
namespace. Mark's reply implies that's not necessarily the case, so I'll
take a tour through clkdev to educate myself.

Cheers,
Mark.

^ permalink raw reply

* [PATCH 1/3] ARM: bios32: use pci_enable_resource to enable PCI resources
From: Will Deacon @ 2014-02-12 16:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140212010650.GI21057@google.com>

Hi Bjorn,

[Adding rmk]

On Wed, Feb 12, 2014 at 01:06:50AM +0000, Bjorn Helgaas wrote:
> On Tue, Feb 04, 2014 at 04:53:02PM +0000, Will Deacon wrote:
> > This patch moves bios32 over to using the generic code for enabling PCI
> > resources. All that's left to take care of is the case of PCI bridges,
> > which need to be enabled for both IO and MEMORY, regardless of the
> > resource types.
> > 
> > A side-effect of this change is that we no longer explicitly enable
> > devices when running in PCI_PROBE_ONLY mode. This stays closer to the
> > meaning of the option and prevents us from trying to enable devices
> > without any assigned resources (the core code refuses to enable
> > resources without parents).
> 
> Heh, I've been looking at this, too :)  I have a similar patch for ARM and
> other architectures with their own versions of pcibios_enable_device().
> 
> Several of them (arm m68k tile tegra unicore32) have this special code that
> enables IO and MEMORY for bridges unconditionally.  But from a PCI
> perspective, I don't know why we should do this unconditionally.  If a
> bridge doesn't have an enabled MEM window or MEM BAR, I don't think we
> should have to enable PCI_COMMAND_MEMORY for it.
> 
> The architectures that do this only check for valid MEM BARs, i.e., they
> only look at resources 0-5, and they don't look at the window resources.

Ok, so they would miss the bridge resources, which would explain the
additional step to enable both IO and MEM unconditionally.

> The architectures that don't enable IO and MEMORY for bridges
> unconditionally check *all* the resources up to PCI_NUM_RESOURCES, which
> includes the BARs, bridge windows, and any IOV resources.
> 
> The generic pci_enable_resources() does check all the resources, so I
> *think* it should be safe for all architectures to use that and just drop
> the check for bridges.  What do you think?

Right, your explanation certainly makes sense to me: if
pci_enable_resources() enables bridge resources, then there's no reason for
the extra logic in the caller.

The problem is, I don't have a platform to test our theory. I've added
Russell, since he might have a relevant ARM platform where we could test our
change.

Will

> > diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> > index 317da88ae65b..9f3c76638689 100644
> > --- a/arch/arm/kernel/bios32.c
> > +++ b/arch/arm/kernel/bios32.c
> > @@ -608,40 +608,25 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> >   */
> >  int pcibios_enable_device(struct pci_dev *dev, int mask)
> >  {
> > -	u16 cmd, old_cmd;
> > -	int idx;
> > -	struct resource *r;
> > +	int err;
> > +	u16 cmd;
> >  
> > -	pci_read_config_word(dev, PCI_COMMAND, &cmd);
> > -	old_cmd = cmd;
> > -	for (idx = 0; idx < 6; idx++) {
> > -		/* Only set up the requested stuff */
> > -		if (!(mask & (1 << idx)))
> > -			continue;
> > +	if (pci_has_flag(PCI_PROBE_ONLY))
> > +		return 0;
> >  
> > -		r = dev->resource + idx;
> > -		if (!r->start && r->end) {
> > -			printk(KERN_ERR "PCI: Device %s not available because"
> > -			       " of resource collisions\n", pci_name(dev));
> > -			return -EINVAL;
> > -		}
> > -		if (r->flags & IORESOURCE_IO)
> > -			cmd |= PCI_COMMAND_IO;
> > -		if (r->flags & IORESOURCE_MEM)
> > -			cmd |= PCI_COMMAND_MEMORY;
> > -	}
> > +	err = pci_enable_resources(dev, mask);
> > +	if (err)
> > +		return err;
> >  
> >  	/*
> >  	 * Bridges (eg, cardbus bridges) need to be fully enabled
> >  	 */
> > -	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
> > +	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
> > +		pci_read_config_word(dev, PCI_COMMAND, &cmd);
> >  		cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
> > -
> > -	if (cmd != old_cmd) {
> > -		printk("PCI: enabling device %s (%04x -> %04x)\n",
> > -		       pci_name(dev), old_cmd, cmd);
> >  		pci_write_config_word(dev, PCI_COMMAND, cmd);
> >  	}
> > +
> >  	return 0;
> >  }
> >  
> > -- 
> > 1.8.2.2
> > 
> 

^ permalink raw reply

* [PATCH 15/17] i2c: i2c-stu300: deprecate class based instantiation
From: Linus Walleij @ 2014-02-12 16:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392026654-5343-16-git-send-email-wsa@the-dreams.de>

On Mon, Feb 10, 2014 at 11:04 AM, Wolfram Sang <wsa@the-dreams.de> wrote:

> Warn users that class based instantiation is going away soon in favour
> of more robust probing and faster bootup times.
>
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> ---
>
> This patch is a suggestion. Looking for an ack by someone who actually uses
> the driver.

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 4/7] spi: pl022: attempt to get sspclk by name
From: Mark Brown @ 2014-02-12 16:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140212161206.GD25957@e106331-lin.cambridge.arm.com>

On Wed, Feb 12, 2014 at 04:12:06PM +0000, Mark Rutland wrote:

> I thought one of the issues before dt was that clocks were in a global
> namespace. Mark's reply implies that's not necessarily the case, so I'll
> take a tour through clkdev to educate myself.

There's both a global namespace and a device local namespace, the most
exact match is used - see the comment on clk_find().  Remember that in
the past clock implementations didn't have to use clkdev at all so the
implementations varied a lot (which is half the problem with drivers
now).  Lots of implementations just used global clock names and didn't
pay any attention to dev.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140212/e86b0994/attachment.sig>

^ permalink raw reply

* [PATCH 10/17] i2c: i2c-nomadik: deprecate class based instantiation
From: Linus Walleij @ 2014-02-12 16:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392026654-5343-11-git-send-email-wsa@the-dreams.de>

On Mon, Feb 10, 2014 at 11:04 AM, Wolfram Sang <wsa@the-dreams.de> wrote:

> Warn users that class based instantiation is going away soon in favour
> of more robust probing and faster bootup times.
>
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
> Cc: Alessandro Rubini <rubini@unipv.it>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> ---
>
> This patch is a suggestion. Looking for an ack by someone who actually uses
> the driver.

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 2/3] arm64: Add Kconfig option for Samsung GH7 SoC family
From: Kumar Gala @ 2014-02-12 16:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140212103824.GF29702@arm.com>


On Feb 12, 2014, at 4:38 AM, Catalin Marinas <catalin.marinas@arm.com> wrote:

> On Tue, Feb 11, 2014 at 11:39:27PM +0000, Olof Johansson wrote:
>> On Mon, Feb 10, 2014 at 10:29 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
>>> This patch adds support for Samsung GH7 SoC in arm64/Kconfig.
>>> 
>>> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
>>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> 
>> The overhead of building one more device tree isn't very large, and I
>> don't see any other need to have a Kconfig entry per SoC at this time.
>> It's of course up to Catalin, but you might just want to always
>> compile all dts files instead.
> 
> For arm64, I thought of getting rid of ARCH_* Kconfig entries entirely,
> only that I haven't heard any strong opinion either way (in which case
> I'll do it, with a risk of single Image getting bigger and bigger and
> people needing smaller Image can trim their .config).

One reason to keep around ARCH_* is for drivers shared between arm and arm64 that depend on it.

- k

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply

* [PATCH 4/7] spi: pl022: attempt to get sspclk by name
From: Arnd Bergmann @ 2014-02-12 16:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140212161206.GD25957@e106331-lin.cambridge.arm.com>

On Wednesday 12 February 2014 16:12:06 Mark Rutland wrote:
> On Wed, Feb 12, 2014 at 01:03:26PM +0000, Arnd Bergmann wrote:
> > On Wednesday 12 February 2014 11:47:40 Mark Rutland wrote:

> From a quick grep, for pl022's SSPCLK we currently have the strings:
> 
> * ssp{0,1}clk
> * spi_clk
> * spi{0,1,2,3}clk
> 
> Though I may have missed a string or two where nodes get amended in more
> specific files. A grep for apb_clk to find neighbours didn't highlight
> any obvious ones.

Ok. Both ssp{0,1}clk and spi{0,1,2,3}clk /only/ appear in
arch/arm/boot/dts/ste-dbx5x0.dtsi and are clearly a bug, so unless
Linus Walleij has objections, I'd declare those to be bugs that
should be fixed by changing the DT file to spi_clk.

> > I noticed that ux500 has uses four different strings, one for each
> > instance, which is obviously a bug and should just be fixed. There is
> > no way this was intentional, and we can just rely on teh fallback
> > if you want to have that anyway.
> 
> Sure, I'll fix those up once we have a preferred name. I guess this
> would be SSPCLK by Russell's comments, I wasn't able to find a prior use
> in the git history, but it would be in keeping with KMIREFCLK as used by
> the pl050 driver.

We do have a few cases of spi_clk, so I'd use that one. Ideally it
should be the string given in the data sheet for the IP block of course,
possibly with capital letters and underscores turned converted to
more regular strings.

> > > I assume that for the non-dt case it's possible to name clock inputs to
> > > a device without the clock being associated with the name globally? If
> > > so we could get rid of the index usage entirely in this case.
> > 
> > Sorry, I don't understand the question.
> 
> I thought one of the issues before dt was that clocks were in a global
> namespace. Mark's reply implies that's not necessarily the case, so I'll
> take a tour through clkdev to educate myself.

The whole point of clkdev is to create a local per-device namespace
so drivers don't need to care about the global names, as far as I understand
it.

	Arnd

^ permalink raw reply

* [BUG] Circular locking dependency - DRM/CMA/MM/hotplug/...
From: Russell King - ARM Linux @ 2014-02-12 16:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52FB9602.1000805@samsung.com>

On Wed, Feb 12, 2014 at 04:40:50PM +0100, Marek Szyprowski wrote:
> Hello,
>
> On 2014-02-11 19:35, Russell King - ARM Linux wrote:
>> The cubox-i4 just hit a new lockdep problem - not quite sure what to
>> make of this - it looks like an interaction between quite a lot of
>> locks - I suspect more than the lockdep code is reporting in its
>> "Possible unsafe locking scenario" report.
>>
>> I'm hoping I've sent this to appropriate people...  if anyone thinks
>> this needs to go to someone else, please forward it.  Thanks.
>
> From the attached log it looks like an issue (AB-BA deadlock) between
> device mutex (&dev->struct_mutex) and mm semaphore (&mm->mmap_sem).
> Similar issue has been discussed quite a long time ago in v4l2
> subsystem:

I think there's more locks involved than just those two.

> https://www.mail-archive.com/linux-media at vger.kernel.org/msg38599.html
> http://www.spinics.net/lists/linux-media/msg40225.html
>
> Solving it probably requires some changes in DRM core. I see no direct
> relation between this issue and CMA itself.

I don't think so - the locking in DRM is pretty sane. Let's take a
look:

>> the existing dependency chain (in reverse order) is:
>> -> #5 (&dev->struct_mutex){+.+...}:
>>         [<c0066f04>] __lock_acquire+0x151c/0x1ca0
>>         [<c0067c28>] lock_acquire+0xa0/0x130
>>         [<c0698180>] mutex_lock_nested+0x5c/0x3ac
>>         [<c0350c30>] drm_gem_mmap+0x40/0xdc
>>         [<c03671d8>] drm_gem_cma_mmap+0x14/0x2c
>>         [<c00ef4f4>] mmap_region+0x3ac/0x59c
>>         [<c00ef9ac>] do_mmap_pgoff+0x2c8/0x370
>>         [<c00dd730>] vm_mmap_pgoff+0x6c/0x9c
>>         [<c00ee1fc>] SyS_mmap_pgoff+0x54/0x98
>>         [<c000e6e0>] ret_fast_syscall+0x0/0x48

vm_mmap_pgoff() takes mm->mmap_sem before calling do_mmap_pgoff().
So, this results in the following locking order:

	mm->mmap_sem
	dev->struct_mutex

>> -> #4 (&mm->mmap_sem){++++++}:
>>         [<c0066f04>] __lock_acquire+0x151c/0x1ca0
>>         [<c0067c28>] lock_acquire+0xa0/0x130
>>         [<c00e6c5c>] might_fault+0x6c/0x94
>>         [<c0335440>] con_set_unimap+0x158/0x27c
>>         [<c032f800>] vt_ioctl+0x1298/0x1388
>>         [<c0323f44>] tty_ioctl+0x168/0xbf4
>>         [<c0115fac>] do_vfs_ioctl+0x84/0x664
>>         [<c01165d0>] SyS_ioctl+0x44/0x64
>>         [<c000e6e0>] ret_fast_syscall+0x0/0x48

vt_ioctl() takes the console lock, so this results in:

	console_lock
	mm->mmap_sem

>> -> #3 (console_lock){+.+.+.}:
>>         [<c0066f04>] __lock_acquire+0x151c/0x1ca0
>>         [<c0067c28>] lock_acquire+0xa0/0x130
>>         [<c006edcc>] console_lock+0x60/0x74
>>         [<c006f7b8>] console_cpu_notify+0x28/0x34
>>         [<c004904c>] notifier_call_chain+0x4c/0x8c
>>         [<c004916c>] __raw_notifier_call_chain+0x1c/0x24
>>         [<c0024124>] __cpu_notify+0x34/0x50
>>         [<c002424c>] cpu_notify_nofail+0x18/0x24
>>         [<c068e168>] _cpu_down+0x100/0x244
>>         [<c068e2dc>] cpu_down+0x30/0x44
>>         [<c036ef8c>] cpu_subsys_offline+0x14/0x18
>>         [<c036af28>] device_offline+0x94/0xbc
>>         [<c036b030>] online_store+0x4c/0x74
>>         [<c0368d3c>] dev_attr_store+0x20/0x2c
>>         [<c016b2e0>] sysfs_kf_write+0x54/0x58
>>         [<c016eaa4>] kernfs_fop_write+0xc4/0x160
>>         [<c0105a54>] vfs_write+0xbc/0x184
>>         [<c0105dfc>] SyS_write+0x48/0x70
>>         [<c000e6e0>] ret_fast_syscall+0x0/0x48

cpu_down() takes cpu_hotplug.lock, so here we have:

	cpu_hotplug.lock
	console_lock

>> -> #2 (cpu_hotplug.lock){+.+.+.}:
>>         [<c0066f04>] __lock_acquire+0x151c/0x1ca0
>>         [<c0067c28>] lock_acquire+0xa0/0x130
>>         [<c0698180>] mutex_lock_nested+0x5c/0x3ac
>>         [<c0024218>] get_online_cpus+0x3c/0x58
>>         [<c00d0ab0>] lru_add_drain_all+0x24/0x190
>>         [<c0101d3c>] migrate_prep+0x10/0x18
>>         [<c00cba04>] alloc_contig_range+0xf4/0x30c
>>         [<c0371588>] dma_alloc_from_contiguous+0x7c/0x130
>>         [<c0018ef8>] __alloc_from_contiguous+0x38/0x12c
>>         [<c0908694>] atomic_pool_init+0x74/0x128
>>         [<c0008850>] do_one_initcall+0x3c/0x164
>>         [<c0903c98>] kernel_init_freeable+0x104/0x1d0
>>         [<c068de54>] kernel_init+0x10/0xec
>>         [<c000e7a8>] ret_from_fork+0x14/0x2c

dma_alloc_from_contiguous takes the cma_mutex, so here we end up with:

	cma_mutex
	cpu_hotplug.lock

>> -> #1 (lock){+.+...}:
>>         [<c0066f04>] __lock_acquire+0x151c/0x1ca0
>>         [<c0067c28>] lock_acquire+0xa0/0x130
>>         [<c0698180>] mutex_lock_nested+0x5c/0x3ac
>>         [<c00d0aa8>] lru_add_drain_all+0x1c/0x190
>>         [<c0101d3c>] migrate_prep+0x10/0x18
>>         [<c00cba04>] alloc_contig_range+0xf4/0x30c
>>         [<c0371588>] dma_alloc_from_contiguous+0x7c/0x130
>>         [<c0018ef8>] __alloc_from_contiguous+0x38/0x12c
>>         [<c0908694>] atomic_pool_init+0x74/0x128
>>         [<c0008850>] do_one_initcall+0x3c/0x164
>>         [<c0903c98>] kernel_init_freeable+0x104/0x1d0
>>         [<c068de54>] kernel_init+0x10/0xec
>>         [<c000e7a8>] ret_from_fork+0x14/0x2c

Ditto - here we have:

	cma_mutex
	lock

where "lock" is nicely named... this is a lock inside lru_add_drain_all()
and under this lock, we call get_online_cpus() and put_online_cpus().
get_online_cpus() takes cpu_hotplug.lock, so here we also have:

	cma_mutex
	lock
	cpu_hotplug.lock

>> -> #0 (cma_mutex){+.+.+.}:
>>         [<c0690850>] print_circular_bug+0x70/0x2f0
>>         [<c0066f68>] __lock_acquire+0x1580/0x1ca0
>>         [<c0067c28>] lock_acquire+0xa0/0x130
>>         [<c0698180>] mutex_lock_nested+0x5c/0x3ac
>>         [<c03716f4>] dma_release_from_contiguous+0xb8/0xf8
>>         [<c00197a4>] __arm_dma_free.isra.11+0x194/0x218
>>         [<c0019868>] arm_dma_free+0x1c/0x24
>>         [<c0366e34>] drm_gem_cma_free_object+0x68/0xb8
>>         [<c0351194>] drm_gem_object_free+0x30/0x38
>>         [<c0351318>] drm_gem_object_handle_unreference_unlocked+0x108/0x148
>>         [<c0351498>] drm_gem_handle_delete+0xb0/0x10c
>>         [<c0351508>] drm_gem_dumb_destroy+0x14/0x18
>>         [<c035e838>] drm_mode_destroy_dumb_ioctl+0x34/0x40
>>         [<c034f918>] drm_ioctl+0x3f4/0x498
>>         [<c0115fac>] do_vfs_ioctl+0x84/0x664
>>         [<c01165d0>] SyS_ioctl+0x44/0x64
>>         [<c000e6e0>] ret_fast_syscall+0x0/0x48

drm_gem_object_unreference_unlocked takes dev->struct_mutex, so:

	dev->struct_mutex
	cma_mutex


So, the full locking dependency tree is this:

CPU0		CPU1		CPU2		CPU3		CPU4
dev->struct_mutex (from #0)
		mm->mmap_sem
		dev->struct_mutex (from #5)
				console_lock (from #4)
				mm->mmap_sem
						cpu_hotplug.lock (from #3)
						console_lock
								cma_mutex (from #2, but also from #1)
								cpu_hotplug.lock
cma_mutex

Which is pretty sick - and I don't think that blaming this solely on V4L2
nor DRM is particularly fair.  I believe the onus is on every author of
one of those locks involved in that chain needs to re-analyse whether
their locking is sane.

For instance, what is cma_mutex protecting?  Is it protecting the CMA
bitmap?

What if we did these changes:

struct page *dma_alloc_from_contiguous(struct device *dev, int count,
                                       unsigned int align)
{
...
        mutex_lock(&cma_mutex);
...
        for (;;) {
                pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
                                                    start, count, mask);
                if (pageno >= cma->count)
                        break;

                pfn = cma->base_pfn + pageno;
+               bitmap_set(cma->bitmap, pageno, count);
+               mutex_unlock(&cma_mutex);
                ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
+               mutex_lock(&cma_mutex);
                if (ret == 0) {
-                       bitmap_set(cma->bitmap, pageno, count);
                        page = pfn_to_page(pfn);
                        break;
-               } else if (ret != -EBUSY) {
+		}
+		bitmap_clear(cma->bitmap, pageno, count);
+		if (ret != -EBUSY) {
                        break;
                }
...
        mutex_unlock(&cma_mutex);
        pr_debug("%s(): returned %p\n", __func__, page);
        return page;
}


bool dma_release_from_contiguous(struct device *dev, struct page *pages,
                                 int count)
{
...
+       free_contig_range(pfn, count);
        mutex_lock(&cma_mutex);
        bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count);
-       free_contig_range(pfn, count);
        mutex_unlock(&cma_mutex);
...
}

which avoids the dependency between cma_mutex and cpu_hotplug.lock ?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [PATCH 05/14] net: axienet: Service completion interrupts ASAP
From: David Laight @ 2014-02-12 16:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cafb13f2ebe4bb996bafb91e405d8609454bb920.1392220536.git.michal.simek@xilinx.com>

From: Michal Simek
> From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
> 
> The packet completion interrupts for TX and RX should be serviced before
> the packets are consumed. This ensures against the degenerate case when a
> new completion interrupt is raised after the handler has exited but before
> the interrupts are cleared. In this case its possible for the ISR to clear
> an unhandled interrupt (leading to potential deadlock).

I would clear the IRQ after processing the last packet, and then do a final
check for another packet.

That reduces the number of interrupts you take and then find there is
no work (because it was done on the previous interrupt).

There is a slight 'gotcha' in that the write to clear the IRQ can easily
get delayed enough the that cpu exits the ISR before the IRQ line
actually drops - leading the unwanted and unclaimed interrupts.
A posted write over PCIe could easily take long enough.

Maybe a hybrid scheme where the IRQ is cleared when the next entry
is still owned by the device would work.

	David

^ permalink raw reply

* [PATCH 1/4] phy: miphy365x: Add Device Tree bindings for the MiPHY365x
From: Mark Rutland @ 2014-02-12 16:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392220985-28189-1-git-send-email-lee.jones@linaro.org>

On Wed, Feb 12, 2014 at 04:03:02PM +0000, Lee Jones wrote:
> The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
> devices. It has 2 ports which it can use for either; both SATA, both
> PCIe or one of each in any configuration.
> 
> Cc: devicetree at vger.kernel.org
> Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  .../devicetree/bindings/phy/phy-miphy365x.txt      | 43 ++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/phy-miphy365x.txt
> 
> diff --git a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
> new file mode 100644
> index 0000000..fdfa7ca
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
> @@ -0,0 +1,43 @@
> +STMicroelectronics STi MIPHY365x PHY binding
> +============================================
> +
> +This binding describes a miphy device that is used to control PHY hardware
> +for SATA and PCIe.
> +
> +Required properties:
> +- compatible: Should be "st,miphy365x-phy"
> +- #phy-cells: Should be 2 (See example)

The first example has #phy-cells = <1>.

What do the cells mean? What are the expected values?

> +- reg:	      Address and length of the register set for the device
> +- reg-names:  The names of the register addresses corresponding to the
> +	      registers filled in "reg".

Whenever there is a ${PROP}-names property, there should be a list of
explicit values, and a description of how it relates to ${PROP}. Without
that it's a bit useless.

Please provide an explicit list of expected names here.

I assume here what you want is something like:

- reg: a list of address + length pairs, one for each entry in reg-names
- reg-names: should contain:
  * "sata0" for the sata0 control registers...
  * "sata1" ...
  * "pcie0" ...
  * "pcie1" ...

> +- st,syscfg : Should be a phandle of the syscfg node.

What's this used for?

Cheers,
Mark.

^ permalink raw reply

* [PATCH 09/12] hwmon: vexpress: Use devm helper for hwmon device registration
From: Guenter Roeck @ 2014-02-12 16:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392206196.848.18.camel@hornet>

On Wed, Feb 12, 2014 at 11:56:36AM +0000, Pawel Moll wrote:
> 
> > I agree with Arnd that it would be nice to get rid of the local macro,
> > but I won't mandate that.
> 
> I actually prefer to have the structures unfolded, but was just trying
> to mimic the trend in other hwmon drivers. No problem - will change this
> gladly.
> 
In general we tend to discourage people to use their own macros -
most of the time it just makes the code more difficult to read.

Guenter

^ permalink raw reply

* [PATCH] bus: imx-weim: support weim-cs-gpr for imx6q-weim
From: Philippe De Muyter @ 2014-02-12 16:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392087011-31629-1-git-send-email-shawn.guo@linaro.org>

Thanks Shawn.

On Tue, Feb 11, 2014 at 10:50:11AM +0800, Shawn Guo wrote:
> For imx6q-weim type of device, there might a WEIM CS space configuration
> register in General Purpose Register controller, e.g. IOMUXC_GPR1 on
> i.MX6Q.
> 
> Depending on which configuration of the following 4 is chosen for given
> system, IOMUXC_GPR1[11:0] should be set up as 0x5, 0x1b, 0x4b or 0x249

As the bits are actually grouped by 3, one could write:
					... as 05, 033, 0113, or 01111
> correspondingly.
> 
> 	CS0(128M) CS1(0M)  CS2(0M)  CS3(0M)
> 	CS0(64M)  CS1(64M) CS2(0M)  CS3(0M)
> 	CS0(64M)  CS1(32M) CS2(32M) CS3(0M)
> 	CS0(32M)  CS1(32M) CS2(32M) CS3(32M)
> 
> The patch creates a table in the driver for above configurations, and
> detects which one is being used for the booting system by looking at
> 'ranges' property of WEIM node.  Thus the WEIM CS GPR can be set up
> automatically at boot time.
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
>  Documentation/devicetree/bindings/bus/imx-weim.txt |    6 ++
>  drivers/bus/imx-weim.c                             |   83 ++++++++++++++++++++
>  2 files changed, 89 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/bus/imx-weim.txt b/Documentation/devicetree/bindings/bus/imx-weim.txt
> index 0fd76c4..d114460f 100644
> --- a/Documentation/devicetree/bindings/bus/imx-weim.txt
> +++ b/Documentation/devicetree/bindings/bus/imx-weim.txt
> @@ -19,6 +19,12 @@ Required properties:
>  
>  			   <cs-number> 0 <physical address of mapping> <size>
>  
> +Optional properties:
> +
> + - fsl,weim-cs-gpr:	Should be the phandle to the General Purpose Register
> +			controller that contains WEIM CS GPR register, e.g.
> +			IOMUXC_GPR1 on i.MX6Q.
> +

Why require that new property ?  It makes things harder to use.

And you could add the body of your commit log here.

>  Timing property for child nodes. It is mandatory, not optional.
>  
>   - fsl,weim-cs-timing:	The timing array, contains timing values for the
> diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c
> index 3ef58c8..9c8a522 100644
> --- a/drivers/bus/imx-weim.c
> +++ b/drivers/bus/imx-weim.c
> @@ -11,6 +11,9 @@
>  #include <linux/clk.h>
>  #include <linux/io.h>
>  #include <linux/of_device.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
> +#include <linux/regmap.h>
>  
>  struct imx_weim_devtype {
>  	unsigned int	cs_count;
> @@ -56,6 +59,83 @@ static const struct of_device_id weim_id_table[] = {
>  };
>  MODULE_DEVICE_TABLE(of, weim_id_table);
>  
> +struct imx6q_weim_gpr {
> +	u32 cssize[4];
> +	u32 gprval;
> +};
> +
> +static const struct imx6q_weim_gpr imx6q_weim_gpr_data[] __initconst = {
> +	{
> +		/* CS0(128M) CS1(0M) CS2(0M) CS3(0M) */
> +		.cssize = { 128, 0, 0, 0 },
> +		.gprval = 0x5,
			05
> +	}, {
> +		/* CS0(64M) CS1(64M) CS2(0M) CS3(0M) */
> +		.cssize = { 64, 64, 0, 0 },
> +		.gprval = 0x1b,
			033
> +	}, {
> +		/* CS0(64M) CS1(32M) CS2(32M) CS3(0M) */
> +		.cssize = { 64, 32, 32, 0 },
> +		.gprval = 0x4b,
			0113
> +	}, {
> +		/* CS0(64M) CS1(32M) CS2(32M) CS3(0M) */
		/* CS0(32M) CS1(32M) CS2(32M) CS3(32M) */
> +		.cssize = { 32, 32, 32, 32 },
> +		.gprval = 0x249,
			01111
> +	},
> +};
> +
> +static int __init imx6q_weim_gpr_setup(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	const struct property *prop;
> +	struct regmap *gpr;
> +	u32 cssize[4] = { 0, 0, 0, 0 };
> +	int len;
> +	int ret;
> +	int i;
> +
> +	gpr = syscon_regmap_lookup_by_phandle(np, "fsl,weim-cs-gpr");

	gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");

> +	if (IS_ERR(gpr)) {
> +		dev_dbg(&pdev->dev, "No weim-cs-gpr to set up\n");
> +		return 0;
> +	}
> +
> +	prop = of_find_property(np, "ranges", &len);
> +	if (prop == NULL)
> +		return -ENOENT;
> +	if (len % (sizeof(u32) * 4))
> +		return -EINVAL;
> +
> +	for (i = 0; i < len / (sizeof(u32) * 4); i++) {
> +		int cs;
> +		/* read cs index */
> +		ret = of_property_read_u32_index(np, "ranges", i * 4, &cs);
> +		if (ret)
> +			return ret;
> +		/* read cs size */
> +		ret = of_property_read_u32_index(np, "ranges", i * 4 + 3,
> +						 &cssize[cs]);
> +		if (ret)
> +			return ret;
> +		/* turn to MB */
> +		cssize[cs] >>= 20;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(imx6q_weim_gpr_data); i++) {
> +		ret = memcmp(cssize, imx6q_weim_gpr_data[i].cssize,
> +			     sizeof(cssize));
> +		if (ret == 0) {
> +			/* Find it. Set up IOMUXC_GPR1[11:0] with the gprval. */

			Found it

> +			regmap_update_bits(gpr, IOMUXC_GPR1, 0xfff,
> +					   imx6q_weim_gpr_data[i].gprval);
> +			return 0;
> +		}
> +	}
> +
> +	dev_err(&pdev->dev, "Invalid 'ranges' configuration\n");
> +	return -EINVAL;
> +}
> +
>  /* Parse and set the timing for this device. */
>  static int __init weim_timing_setup(struct device_node *np, void __iomem *base,
>  				    const struct imx_weim_devtype *devtype)
> @@ -92,6 +172,9 @@ static int __init weim_parse_dt(struct platform_device *pdev,
>  	struct device_node *child;
>  	int ret;
>  
> +	if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6q-weim"))
> +		imx6q_weim_gpr_setup(pdev);
> +
>  	for_each_child_of_node(pdev->dev.of_node, child) {
>  		if (!child->name)
>  			continue;
> -- 
> 1.7.9.5
> 

Now the most important : it works.  I have tested it successfully for the
4 combinations.

Code could probably be made shorter by using 'of_prop_next_u32' and building
the gprval incrementally, then checking it against the four possible values,
though.

But, again, thanks, Shawn

-- 
Philippe De Muyter +32 2 6101532 Macq SA rue de l'Aeronef 2 B-1140 Bruxelles

^ permalink raw reply

* [RFC/PATCH 1/3] of: Add early randomness hooks
From: Grant Likely @ 2014-02-12 16:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392168805-14200-2-git-send-email-lauraa@codeaurora.org>

On Tue, 11 Feb 2014 17:33:23 -0800, Laura Abbott <lauraa@codeaurora.org> wrote:
> Until randomness is added to the kernel's pools, random
> numbers returned may not be truly 'random'. Randomness comes
> from a variety of sources in the kernel but much of the
> randomness comes from device related initialization. This
> means that any random numbers that are needed before drivers
> are initialized (e.g. stack canary) may not be truely random.
> Fix this by build a list of functions that can be used to add
> randomness to the kernel's pools very early. The functions are
> tied to particular compatible strings of devicetree nodes. The
> flattened devicetree is scanned and if the node is present the
> function is called. Note that this must happen on the flattened
> devicetree to ensure the randomness gets added to the pool
> early enough to make a difference.
> 
> Signed-off-by: Laura Abbott <lauraa@codeaurora.org>

Intriguing solution. Looks good to me, but some comments below...

> ---
>  drivers/of/Kconfig                |    7 ++++++
>  drivers/of/Makefile               |    1 +
>  drivers/of/fdt.c                  |    7 ++++++
>  drivers/of/of_randomness.c        |   43 +++++++++++++++++++++++++++++++++++++
>  include/asm-generic/vmlinux.lds.h |    5 ++++
>  include/linux/of_randomness.h     |   42 ++++++++++++++++++++++++++++++++++++
>  6 files changed, 105 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/of/of_randomness.c
>  create mode 100644 include/linux/of_randomness.h
> 
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index c6973f1..6ae4a38 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -75,4 +75,11 @@ config OF_MTD
>  	depends on MTD
>  	def_bool y
>  
> +config OF_RANDOMNESS
> +	def_bool n

There should be the option to turn this off, particularly if it turns
out to be expensive in terms of boot time.

> +	depends on OF_FLATTREE && ARCH_WANT_OF_RANDOMNESS
> +        help
> +	  OpenFirmware hooks to scan for device randomness
> +	  via flat devicetree

Inconsistent whitespace

> +
>  endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index efd0510..0ce02d1 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
>  obj-$(CONFIG_OF_PCI)	+= of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)	+= of_mtd.o
> +obj-$(CONFIG_OF_RANDOMNESS)	+= of_randomness.o
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 758b4f8..c25960e 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -15,6 +15,7 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_fdt.h>
> +#include <linux/of_randomness.h>
>  #include <linux/string.h>
>  #include <linux/errno.h>
>  #include <linux/slab.h>
> @@ -889,6 +890,12 @@ bool __init early_init_dt_scan(void *params)
>  	/* Setup memory, calling early_init_dt_add_memory_arch */
>  	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
>  
> +#ifdef CONFIG_OF_RANDOMNESS
> +	/* Add device randomness */
> +	of_scan_flat_dt(early_init_dt_scan_early_randomness, NULL);
> +#endif

Drop the #ifdef in fdt.c and use static inlines in the header file. One
that does the of_scan_flat_dt() call, and one empty stub for the
!CONFIG_OF_RANDOMNESS case.

I would also bypass the of_scan_flat_dt call entirely if the
__early_random_funcs list is empty.

> +
> +
>  	return true;
>  }
>  
> diff --git a/drivers/of/of_randomness.c b/drivers/of/of_randomness.c
> new file mode 100644
> index 0000000..9d23624
> --- /dev/null
> +++ b/drivers/of/of_randomness.c
> @@ -0,0 +1,43 @@
> +/* Copyright (c) 2013-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/kernel.h>
> +#include <linux/random.h>
> +#include <linux/string.h>
> +#include <linux/of_randomness.h>
> +#include <linux/of_fdt.h>
> +
> +int __init early_init_dt_scan_early_randomness(unsigned long node,
> +					const char *uname,
> +					int depth, void *data)
> +{
> +	struct early_random_func *f;
> +	void *prop;
> +	unsigned long len;
> +
> +	prop = of_get_flat_dt_prop(node, "compatible", &len);
> +
> +	if (!prop)
> +		return 0;
> +
> +	for (f = __early_random_funcs_start;
> +	     f < __early_random_funcs_end;
> +	     f++) {
> +		pr_debug("Check compat %s addr %p against %s\n",
> +			f->compat_string, f->add_randomness, (char *)prop);
> +		if (strcmp(prop, f->compat_string) == 0)
> +			f->add_randomness(node);
> +	}
> +
> +	return 0;
> +}
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index bc2121f..e5b8be9 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -645,6 +645,11 @@
>  		*(.security_initcall.init)				\
>  		VMLINUX_SYMBOL(__security_initcall_end) = .;
>  
> +#define EARLY_RANDOM_FUNCS						\
> +		VMLINUX_SYMBOL(__early_random_funcs_start) = .;		\
> +		*(.earlyrandom.init)					\
> +		VMLINUX_SYMBOL(__early_random_funcs_end) = .;
> +
>  #ifdef CONFIG_BLK_DEV_INITRD
>  #define INIT_RAM_FS							\
>  	. = ALIGN(4);							\
> diff --git a/include/linux/of_randomness.h b/include/linux/of_randomness.h
> new file mode 100644
> index 0000000..b8b4532
> --- /dev/null
> +++ b/include/linux/of_randomness.h
> @@ -0,0 +1,42 @@
> +/* Copyright (c) 2013-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 LINUX_OF_RANDOMNESS_H
> +#define LINUX_OF_RANDOMNESS_H
> +
> +extern int early_init_dt_scan_early_randomness(unsigned long node,
> +					  const char *uname,
> +					  int depth, void *data);
> +
> +#ifdef CONFIG_OF_RANDOMNESS
> +
> +struct early_random_func {
> +	char *compat_string;
> +	void (*add_randomness)(unsigned long fdt_node);
> +};
> +
> +extern struct early_random_func __early_random_funcs_start[];
> +extern struct early_random_func __early_random_funcs_end[];
> +
> +#define EARLY_RANDOM_FUNC(c, f)    \
> +static struct early_random_func __early_rand##f __used \
> +	__attribute((__section__(".earlyrandom.init"))) = { \
> +		.compat_string = c, \
> +		.add_randomness = f\
> +	} \
> +
> +#else
> +
> +#define EARLY_RANDOM_FUNC(f, e)
> +#endif
> +
> +#endif
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
> 

^ permalink raw reply

* [RFC/PATCH 2/3] arm: Add ARCH_WANT_OF_RANDOMNESS
From: Grant Likely @ 2014-02-12 16:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392168805-14200-3-git-send-email-lauraa@codeaurora.org>

On Tue, 11 Feb 2014 17:33:24 -0800, Laura Abbott <lauraa@codeaurora.org> wrote:
> The stack canary for ARM is currently the same across reboots
> due to lack of randomness early enough. Add ARCH_WANT_OF_RANDOMNESS
> to allow devices to add whatever randomness they need.
> 
> Signed-off-by: Laura Abbott <lauraa@codeaurora.org>

Do you have a draft patch for a user of this yet?

g.

> ---
>  arch/arm/Kconfig              |    3 +++
>  arch/arm/kernel/vmlinux.lds.S |    1 +
>  2 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index e254198..7ab0db1 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -222,6 +222,9 @@ config NEED_RET_TO_USER
>  config ARCH_MTD_XIP
>  	bool
>  
> +config ARCH_WANT_OF_RANDOMNESS
> +	def_bool n
> +
>  config VECTORS_BASE
>  	hex
>  	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
> index 7bcee5c..2198258 100644
> --- a/arch/arm/kernel/vmlinux.lds.S
> +++ b/arch/arm/kernel/vmlinux.lds.S
> @@ -202,6 +202,7 @@ SECTIONS
>  		INIT_SETUP(16)
>  		INIT_CALLS
>  		CON_INITCALL
> +		EARLY_RANDOM_FUNCS
>  		SECURITY_INITCALL
>  		INIT_RAM_FS
>  	}
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
> 

^ permalink raw reply

* [PATCH v2 0/9] ARM: multi-platform kconfig cleanup and mach-virt removal
From: Arnd Bergmann @ 2014-02-12 16:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL_JsqJkCXSFJZzRBRTrKh16PoBjvF95uKJbZAic-pk3htf_jg@mail.gmail.com>

On Wednesday 12 February 2014 08:07:12 Rob Herring wrote:
> On Wed, Feb 12, 2014 at 7:46 AM, Will Deacon <will.deacon@arm.com> wrote:
> > On Wed, Feb 12, 2014 at 01:26:41PM +0000, Arnd Bergmann wrote:
> >> On Tuesday 11 February 2014, Rob Herring wrote:
> >> > The previous version [1] was mainly a discussion about v6 vs. v6K.
> >> > Several platforms have this wrong and incorrectly select v6 when the
> >> > more optimal v6K option could be used. After more research, my memory
> >> > about i.MX31 was wrong and it does need to remain v6.
> >>
> >> Just curious: do you have more information on this? Are all i.MX31 ARMv6
> >> and all i.MX35 v6k as the current Kconfig claims,  or is it more
> >> complicated?
> >
> > Slightly tangential, but the one to watch out for is 1136. Prior to r1 (i.e.
> > r0pX), it is v6 but r1pX+ are v6k (without SMP).
> 
> Right. I originally was thinking that the MX31 1.x was r0pX and MX31
> 2.x was r1pX and that there are no 1.x chips around. However, after
> checking the errata sheet, 1.x is r0p1 and 2.x is r0p4. It must have
> been one of the other 1136 chips we did that moved to r1pX.

Ok.

> >> * integrator and realview apparently allow both CPU_V6 and CPU_V6K
> >>   to be manually selected. Is that actually the correct behavior
> >>   in that both kinds of core tiles exist?
> >
> > I have 1136 r0p1 on an integrator CP, so I suppose it could also take an
> > 1136 r1pX without any trouble.
> 
> Presumably some of both exist which is why the config options are as they are?

Possible, but I wouldn't trust that part of the kernel very far. Especially
the MMU-less CPUs in there seem to be listed a bit randomly.

On the topic of V6, we don't support CPU_V6T2 at all, though I assume that
there is an ARM1156 core tile for integrator and realview, and we support
running the V6/V6K parts with MMU turned off. Would all revisions of ARM1156
work with CPU_V6K and !MMU?

	Arnd

^ permalink raw reply

* [PATCH 4/4] ARM: Delete asm/system.h
From: Arnd Bergmann @ 2014-02-12 16:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140212154615.2405.88996.stgit@warthog.procyon.org.uk>

On Wednesday 12 February 2014 15:46:15 David Howells wrote:
> Delete ARM's asm/system.h.  It's the last holdout and should be got rid of.
> 
> This builds for defconfig, lpc32xx_defconfig, exynos_defconfig + XEN, the
> previous changed to a Gemini system and an omap3 config with TI_DAVINCI_EMAC.
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: Russell King <linux@arm.linux.org.uk>
> cc: linux-arm-kernel at lists.infradead.org

Acked-by: Arnd Bergmann <arnd@arndb.de>

I've added this to my randconfig builder, will let you know when unexpected
bugs show up (probably won't).

	Arnd

^ permalink raw reply

* [PATCH 4/4] phy: miphy365x: Provide support for the MiPHY356x Generic PHY
From: Mark Rutland @ 2014-02-12 16:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392220985-28189-4-git-send-email-lee.jones@linaro.org>

On Wed, Feb 12, 2014 at 04:03:05PM +0000, Lee Jones wrote:
> The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
> devices. It has 2 ports which it can use for either; both SATA, both
> PCIe or one of each in any configuration.
>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/phy/Kconfig         |   8 +
>  drivers/phy/Makefile        |   1 +
>  drivers/phy/phy-miphy365x.c | 634 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 643 insertions(+)
>  create mode 100644 drivers/phy/phy-miphy365x.c
>

[...]

> +static int miphy365x_phy_get_base_addr(struct platform_device *pdev,
> +                                      struct miphy365x_phy *phy, u8 port)
> +{
> +       struct resource *res;
> +       char sata[16];
> +       char pcie[16];

Isn't 6 enough for either of these? There are at most two ports IIUC, so
we only need a single character for the port number.

> +
> +       sprintf(sata, "sata%d", port);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, sata);
> +       if (!res)
> +               return -ENODEV;
> +
> +       phy->sata = devm_ioremap(&pdev->dev, res->start, resource_size(res));
> +       if (!phy->sata)
> +               return -ENOMEM;
> +
> +       sprintf(pcie, "pcie%d", port);
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pcie);
> +       if (!res)
> +               return -ENODEV;
> +
> +       phy->pcie = devm_ioremap(&pdev->dev, res->start, resource_size(res));
> +       if (!phy->pcie)
> +               return -ENOMEM;
> +
> +       return 0;
> +}
> +
> +static int miphy365x_phy_of_probe(struct device_node *np,
> +                                 struct miphy365x_dev *phy_dev)
> +{
> +       const char *sata_gen;
> +
> +       phy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
> +       if (IS_ERR(phy_dev->regmap)) {
> +               dev_err(phy_dev->dev, "No syscfg phandle specified\n");
> +               return PTR_ERR(phy_dev->regmap);
> +       }
> +
> +       /* Default */
> +       phy_dev->sata_gen = SATA_GEN1;
> +
> +       of_property_read_string(np, "st,sata_gen", &sata_gen);

This wasn't in the binding documentation. It also violates dt style;
s/_/-/

Could these not be numbers, or can this not come from elsewhere?

Or are there some crazy SATA generations to support?

> +       if (sata_gen) {
> +               if (!strcmp(sata_gen, "gen3"))
> +                       phy_dev->sata_gen = SATA_GEN3;
> +               else if (!strcmp(sata_gen, "gen2"))
> +                       phy_dev->sata_gen = SATA_GEN2;
> +       }
> +
> +       phy_dev->pcie_tx_pol_inv =
> +               of_property_read_bool(np, "st,pcie_tx_pol_inv");
> +
> +       phy_dev->sata_tx_pol_inv =
> +               of_property_read_bool(np, "st,sata_tx_pol_inv");

Likewise for both of these on the first two points.

> +
> +       return 0;
> +}
> +
> +static int miphy365x_phy_probe(struct platform_device *pdev)
> +{
> +       struct device_node *np = pdev->dev.of_node;
> +       struct miphy365x_dev *phy_dev;
> +       struct device *dev = &pdev->dev;
> +       struct phy_provider *provider;
> +       u8 port;
> +       int ret;
> +
> +       if (!np) {
> +               dev_err(dev, "No DT found\n");

s/DT/node/ ?

Cheers,
Mark.

^ permalink raw reply

* [PATCH 1/1] mfd: max665x: Differentiate between MAX665X devices
From: Lee Jones @ 2014-02-12 16:58 UTC (permalink / raw)
  To: linux-arm-kernel

This driver is pretty sparse at the moment, but once we start to add
more functionality it's highly probable that we'll be required to
differentiate between supported devices. To enable us to do that
efficiently via Device Tree we need to separate out the compatible
strings, one per variant.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/max665x.c               | 3 ++-
 include/linux/mfd/max665x-private.h | 5 +++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/max665x.c b/drivers/mfd/max665x.c
index 54fdc11..3bcb765b0 100644
--- a/drivers/mfd/max665x.c
+++ b/drivers/mfd/max665x.c
@@ -71,7 +71,8 @@ static int max665x_remove(struct i2c_client *i2c)
 }
 
 static struct of_device_id max665x_dt_match[] = {
-	{ .compatible = "maxim,max665x" },
+	{ .compatible = "maxim,max6650", .data = (void *)MAX6550 },
+	{ .compatible = "maxim,max6651", .data = (void *)MAX6551 },
 	{},
 };
 MODULE_DEVICE_TABLE(of, max665x_dt_match);
diff --git a/include/linux/mfd/max665x-private.h b/include/linux/mfd/max665x-private.h
index 293db4b..1578a04 100644
--- a/include/linux/mfd/max665x-private.h
+++ b/include/linux/mfd/max665x-private.h
@@ -23,6 +23,11 @@
 #include <linux/i2c.h>
 #include <linux/regmap.h>
 
+enum max655x_id {
+	MAX6550 = 0,
+	MAX6551,
+}
+
 struct max665x_dev {
 	struct device *dev;
 	struct mutex iolock;
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH v2 0/9] ARM: multi-platform kconfig cleanup and mach-virt removal
From: Marc Zyngier @ 2014-02-12 17:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1726732.KPDAFqxz2K@wuerfel>

On 12/02/14 16:53, Arnd Bergmann wrote:
> 
> On the topic of V6, we don't support CPU_V6T2 at all, though I assume that
> there is an ARM1156 core tile for integrator and realview, and we support
> running the V6/V6K parts with MMU turned off. Would all revisions of ARM1156
> work with CPU_V6K and !MMU?

CPU_V6 and !MMU should work. V6K might, but that requires close
inspection (WFE, SEV shouldn't be used in UP context)...

Full disclosure: I happen to have a *brand new*, freshly unwrapped
ARM1156 core tile for a Versatile EB. All it requires is a victim with
time on their hand...

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply


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