Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 13/16] cpuidle: mvebu: add Armada 38x support
From: Daniel Lezcano @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406120453-29291-14-git-send-email-thomas.petazzoni@free-electrons.com>

On 07/23/2014 03:00 PM, Thomas Petazzoni wrote:
> This commit adds the list of cpuidle states supported by the Armada
> 38x SoC in the cpuidle-mvebu-v7 driver, as well as the necessary logic
> around it to support this SoC.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   drivers/cpuidle/cpuidle-mvebu-v7.c | 29 ++++++++++++++++++++++++++++-
>   1 file changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
> index d23597f..45371bb 100644
> --- a/drivers/cpuidle/cpuidle-mvebu-v7.c
> +++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
> @@ -1,5 +1,5 @@
>   /*
> - * Marvell Armada 370 and Armada XP SoC cpuidle driver
> + * Marvell Armada 370, 38x and XP SoC cpuidle driver
>    *
>    * Copyright (C) 2014 Marvell
>    *
> @@ -86,6 +86,21 @@ static struct cpuidle_driver armada370_idle_driver = {
>   	.state_count = 2,
>   };
>
> +static struct cpuidle_driver armada38x_idle_driver = {
> +	.name			= "armada_38x_idle",
> +	.states[0]		= ARM_CPUIDLE_WFI_STATE,
> +	.states[1]		= {
> +		.enter			= mvebu_v7_enter_idle,
> +		.exit_latency		= 10,
> +		.power_usage		= 5,
> +		.target_residency	= 100,
> +		.flags			= CPUIDLE_FLAG_TIME_VALID,
> +		.name			= "Idle",
> +		.desc			= "CPU and SCU power down",
> +	},
> +	.state_count = 2,
> +};
> +
>   static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
>   {
>   	mvebu_v7_cpu_suspend = pdev->dev.platform_data;
> @@ -94,6 +109,8 @@ static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
>   		return cpuidle_register(&armadaxp_idle_driver, NULL);
>   	else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-370"))
>   		return cpuidle_register(&armada370_idle_driver, NULL);
> +	else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-38x"))
> +		return cpuidle_register(&armada38x_idle_driver, NULL);
>   	else
>   		return -EINVAL;
>   }
> @@ -118,6 +135,16 @@ static struct platform_driver armada370_cpuidle_plat_driver = {
>
>   module_platform_driver(armada370_cpuidle_plat_driver);
>
> +static struct platform_driver armada38x_cpuidle_plat_driver = {
> +	.driver = {
> +		.name = "cpuidle-armada-38x",
> +		.owner = THIS_MODULE,
> +	},
> +	.probe = mvebu_v7_cpuidle_probe,
> +};
> +
> +module_platform_driver(armada38x_cpuidle_plat_driver);
> +
>   MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
>   MODULE_DESCRIPTION("Marvell EBU v7 cpuidle driver");
>   MODULE_LICENSE("GPL");
>


-- 
  <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

^ permalink raw reply

* [PATCH v11 8/8] ARM: berlin: enable the eSATA interface on the BG2Q DMP
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406193450-17283-1-git-send-email-antoine.tenart@free-electrons.com>

The BG2Q has an AHCI SATA controller with an eSATA interface. Enable it.
Only enable the first port, the BG2Q DMP does not support the second one.

Signed-off-by: Antoine T?nart <antoine.tenart@free-electrons.com>
---
 arch/arm/boot/dts/berlin2q-marvell-dmp.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
index 995150f93795..385f6af64d0c 100644
--- a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
+++ b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
@@ -37,3 +37,11 @@
 &uart0 {
 	status = "okay";
 };
+
+&sata0 {
+	status = "okay";
+};
+
+&sata_phy {
+	status = "okay";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 7/8] ARM: berlin: add the AHCI node for the BG2Q
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406193450-17283-1-git-send-email-antoine.tenart@free-electrons.com>

The BG2Q has an AHCI SATA controller. Add the corresponding nodes
(AHCI, PHY) into its device tree.

Signed-off-by: Antoine T?nart <antoine.tenart@free-electrons.com>
---
 arch/arm/boot/dts/berlin2q.dtsi | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 635a16a64cb4..658975d22df7 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -303,6 +303,45 @@
 			clock-names = "refclk";
 		};
 
+		ahci: sata at e90000 {
+			compatible = "marvell,berlin2q-ahci", "generic-ahci";
+			reg = <0xe90000 0x1000>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&chip CLKID_SATA>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			sata0: sata-port at 0 {
+				reg = <0>;
+				phys = <&sata_phy 0>;
+				status = "disabled";
+			};
+
+			sata1: sata-port at 1 {
+				reg = <1>;
+				phys = <&sata_phy 1>;
+				status = "disabled";
+			};
+		};
+
+		sata_phy: phy at e900a0 {
+			compatible = "marvell,berlin2q-sata-phy";
+			reg = <0xe900a0 0x200>;
+			clocks = <&chip CLKID_SATA>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			#phy-cells = <1>;
+			status = "disabled";
+
+			sata-phy at 0 {
+				reg = <0>;
+			};
+
+			sata-phy at 1 {
+				reg = <1>;
+			};
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 6/8] Documentation: bindings: document the sub-nodes AHCI bindings
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406193450-17283-1-git-send-email-antoine.tenart@free-electrons.com>

The libahci now allows to use multiple PHYs and to represent each port
as a sub-node. Add these bindings to the documentation.

Signed-off-by: Antoine T?nart <antoine.tenart@free-electrons.com>
---
 .../devicetree/bindings/ata/ahci-platform.txt      | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index c96d8dcf98fd..93a6ad3965ca 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -3,6 +3,10 @@
 SATA nodes are defined to describe on-chip Serial ATA controllers.
 Each SATA controller should have its own node.
 
+It is possible, but not required, to represent each port as a sub-node.
+It allows to enable each port independently when dealing with multiple
+PHYs.
+
 Required properties:
 - compatible        : compatible string, one of:
   - "allwinner,sun4i-a10-ahci"
@@ -14,18 +18,35 @@ Required properties:
   - "snps,dwc-ahci"
   - "snps,exynos5440-ahci"
   - "snps,spear-ahci"
+  - "generic-ahci"
 - interrupts        : <interrupt mapping for SATA IRQ>
 - reg               : <registers mapping>
 
+Please note that when using "generic-ahci" you must also specify a SoC specific
+compatible:
+	compatible = "manufacturer,soc-model-ahci", "generic-ahci";
+
 Optional properties:
 - dma-coherent      : Present if dma operations are coherent
 - clocks            : a list of phandle + clock specifier pairs
 - target-supply     : regulator for SATA target power
+- phys              : reference to the SATA PHY node
+- phy-names         : must be "sata-phy"
 
 "fsl,imx53-ahci", "fsl,imx6q-ahci" required properties:
 - clocks            : must contain the sata, sata_ref and ahb clocks
 - clock-names       : must contain "ahb" for the ahb clock
 
+Required properties when using sub-nodes:
+- #address-cells    : number of cells to encode an address
+- #size-cells       : number of cells representing the size of an address
+
+
+Sub-nodes required properties:
+- reg               : the port number
+- phys              : reference to the SATA PHY node
+
+
 Examples:
         sata at ffe08000 {
 		compatible = "snps,spear-ahci";
@@ -40,3 +61,23 @@ Examples:
 		clocks = <&pll6 0>, <&ahb_gates 25>;
 		target-supply = <&reg_ahci_5v>;
 	};
+
+With sub-nodes:
+	sata at f7e90000 {
+		compatible = "marvell,berlin2q-achi", "generic-ahci";
+		reg = <0xe90000 0x1000>;
+		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&chip CLKID_SATA>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sata0: sata-port at 0 {
+			reg = <0>;
+			phys = <&sata_phy 0>;
+		};
+
+		sata1: sata-port at 1 {
+			reg = <1>;
+			phys = <&sata_phy 1>;
+		};
+	};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 5/8] ata: ahci_platform: add a generic AHCI compatible
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406193450-17283-1-git-send-email-antoine.tenart@free-electrons.com>

The ahci_platform driver is a generic driver using the libahci_platform
functions. Add a generic compatible to avoid having an endless list of
compatibles with no differences for the same driver.

Signed-off-by: Antoine T?nart <antoine.tenart@free-electrons.com>
---
 drivers/ata/ahci_platform.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 95f9ca82082a..61b15e784020 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -77,6 +77,8 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
 			 ahci_platform_resume);
 
 static const struct of_device_id ahci_of_match[] = {
+	{ .compatible = "generic-ahci", },
+	/* Keep the following compatibles for device tree compatibility */
 	{ .compatible = "snps,spear-ahci", },
 	{ .compatible = "snps,exynos5440-ahci", },
 	{ .compatible = "ibm,476gtr-ahci", },
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 4/8] ata: libahci: allow to use multiple PHYs
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406193450-17283-1-git-send-email-antoine.tenart@free-electrons.com>

The current implementation of the libahci does not allow to use multiple
PHYs. This patch adds the support of multiple PHYs by the libahci while
keeping the old bindings valid for device tree compatibility.

This introduce a new way of defining SATA ports in the device tree, with
one port per sub-node. This as the advantage of allowing a per port
configuration. Because some ports may be accessible but disabled in the
device tree, the port_map mask is computed automatically when using
this.

Signed-off-by: Antoine T?nart <antoine.tenart@free-electrons.com>
---
 drivers/ata/ahci.h             |   7 +-
 drivers/ata/libahci_platform.c | 190 ++++++++++++++++++++++++++++++++---------
 2 files changed, 157 insertions(+), 40 deletions(-)

diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index cb8d58926851..47de53284ad7 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -332,7 +332,12 @@ struct ahci_host_priv {
 	bool			got_runtime_pm; /* Did we do pm_runtime_get? */
 	struct clk		*clks[AHCI_MAX_CLKS]; /* Optional */
 	struct regulator	*target_pwr;	/* Optional */
-	struct phy		*phy;		/* If platform uses phy */
+	/*
+	 * If platform uses PHYs. There is a 1:1 relation between the port number and
+	 * the PHY position in this array.
+	 */
+	struct phy		**phys;
+	unsigned		nports;		/* Number of ports */
 	void			*plat_data;	/* Other platform data */
 	/*
 	 * Optional ahci_start_engine override, if not set this gets set to the
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index db9b90d876dd..095df56432d9 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -39,6 +39,67 @@ static struct scsi_host_template ahci_platform_sht = {
 };
 
 /**
+ * ahci_platform_enable_phys - Enable PHYs
+ * @hpriv: host private area to store config values
+ *
+ * This function enables all the PHYs found in hpriv->phys, if any.
+ * If a PHY fails to be enabled, it disables all the PHYs already
+ * enabled in reverse order and returns an error.
+ *
+ * RETURNS:
+ * 0 on success otherwise a negative error code
+ */
+int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
+{
+	int rc, i;
+
+	for (i = 0; i < hpriv->nports; i++) {
+		if (!hpriv->phys[i])
+			continue;
+
+		rc = phy_init(hpriv->phys[i]);
+		if (rc)
+			goto disable_phys;
+
+		rc = phy_power_on(hpriv->phys[i]);
+		if (rc) {
+			phy_exit(hpriv->phys[i]);
+			goto disable_phys;
+		}
+	}
+
+	return 0;
+
+disable_phys:
+	while (--i >= 0) {
+		phy_power_off(hpriv->phys[i]);
+		phy_exit(hpriv->phys[i]);
+	}
+	return rc;
+}
+EXPORT_SYMBOL_GPL(ahci_platform_enable_phys);
+
+/**
+ * ahci_platform_disable_phys - Enable PHYs
+ * @hpriv: host private area to store config values
+ *
+ * This function disables all PHYs found in hpriv->phys.
+ */
+void ahci_platform_disable_phys(struct ahci_host_priv *hpriv)
+{
+	int i;
+
+	for (i = 0; i < hpriv->nports; i++) {
+		if (!hpriv->phys[i])
+			continue;
+
+		phy_power_off(hpriv->phys[i]);
+		phy_exit(hpriv->phys[i]);
+	}
+}
+EXPORT_SYMBOL_GPL(ahci_platform_disable_phys);
+
+/**
  * ahci_platform_enable_clks - Enable platform clocks
  * @hpriv: host private area to store config values
  *
@@ -92,7 +153,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
  * following order:
  * 1) Regulator
  * 2) Clocks (through ahci_platform_enable_clks)
- * 3) Phy
+ * 3) Phys
  *
  * If resource enabling fails at any point the previous enabled resources
  * are disabled in reverse order.
@@ -114,17 +175,9 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
 	if (rc)
 		goto disable_regulator;
 
-	if (hpriv->phy) {
-		rc = phy_init(hpriv->phy);
-		if (rc)
-			goto disable_clks;
-
-		rc = phy_power_on(hpriv->phy);
-		if (rc) {
-			phy_exit(hpriv->phy);
-			goto disable_clks;
-		}
-	}
+	rc = ahci_platform_enable_phys(hpriv);
+	if (rc)
+		goto disable_clks;
 
 	return 0;
 
@@ -144,16 +197,13 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
  *
  * This function disables all ahci_platform managed resources in the
  * following order:
- * 1) Phy
+ * 1) Phys
  * 2) Clocks (through ahci_platform_disable_clks)
  * 3) Regulator
  */
 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
 {
-	if (hpriv->phy) {
-		phy_power_off(hpriv->phy);
-		phy_exit(hpriv->phy);
-	}
+	ahci_platform_disable_phys(hpriv);
 
 	ahci_platform_disable_clks(hpriv);
 
@@ -187,7 +237,7 @@ static void ahci_platform_put_resources(struct device *dev, void *res)
  * 2) regulator for controlling the targets power (optional)
  * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
  *    or for non devicetree enabled platforms a single clock
- *	4) phy (optional)
+ *	4) phys (optional)
  *
  * RETURNS:
  * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
@@ -197,7 +247,9 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct ahci_host_priv *hpriv;
 	struct clk *clk;
-	int i, rc = -ENOMEM;
+	struct device_node *child;
+	int i, enabled_ports = 0, rc = -ENOMEM;
+	u32 mask_port_map = 0;
 
 	if (!devres_open_group(dev, NULL, GFP_KERNEL))
 		return ERR_PTR(-ENOMEM);
@@ -246,27 +298,87 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
 		hpriv->clks[i] = clk;
 	}
 
-	hpriv->phy = devm_phy_get(dev, "sata-phy");
-	if (IS_ERR(hpriv->phy)) {
-		rc = PTR_ERR(hpriv->phy);
-		switch (rc) {
-		case -ENOSYS:
-			/* No PHY support. Check if PHY is required. */
-			if (of_find_property(dev->of_node, "phys", NULL)) {
-				dev_err(dev, "couldn't get sata-phy: ENOSYS\n");
+	hpriv->nports = of_get_child_count(dev->of_node);
+
+	if (hpriv->nports) {
+		hpriv->phys = devm_kzalloc(dev,
+					   hpriv->nports * sizeof(*hpriv->phys),
+					   GFP_KERNEL);
+		if (!hpriv->phys) {
+			rc = -ENOMEM;
+			goto err_out;
+		}
+
+		for_each_child_of_node(dev->of_node, child) {
+			u32 port;
+
+			if (!of_device_is_available(child))
+				continue;
+
+			if (of_property_read_u32(child, "reg", &port)) {
+				rc = -EINVAL;
 				goto err_out;
 			}
-		case -ENODEV:
-			/* continue normally */
-			hpriv->phy = NULL;
-			break;
 
-		case -EPROBE_DEFER:
-			goto err_out;
+			if (port >= hpriv->nports) {
+				dev_warn(dev, "invalid port number %d\n", port);
+				continue;
+			}
 
-		default:
-			dev_err(dev, "couldn't get sata-phy\n");
-			goto err_out;
+			mask_port_map |= BIT(port);
+
+			hpriv->phys[port] = devm_of_phy_get(dev, child, NULL);
+			if (IS_ERR(hpriv->phys[port])) {
+				rc = PTR_ERR(hpriv->phys[port]);
+				dev_err(dev,
+					"couldn't get PHY in node %s: %d\n",
+					child->name, rc);
+				goto err_out;
+			}
+
+			enabled_ports++;
+		}
+		if (!enabled_ports) {
+			dev_warn(dev, "No port enabled\n");
+			return ERR_PTR(-ENODEV);
+		}
+
+		if (!hpriv->mask_port_map)
+			hpriv->mask_port_map = mask_port_map;
+	} else {
+		/*
+		 * If no sub-node was found, keep this for device tree
+		 * compatibility
+		 */
+		struct phy *phy = devm_phy_get(dev, "sata-phy");
+		if (!IS_ERR(phy)) {
+			hpriv->phys = devm_kzalloc(dev, sizeof(*hpriv->phys),
+						   GFP_KERNEL);
+			if (!hpriv->phys) {
+				rc = -ENOMEM;
+				goto err_out;
+			}
+
+			hpriv->phys[0] = phy;
+			hpriv->nports = 1;
+		} else {
+			rc = PTR_ERR(phy);
+			switch (rc) {
+				case -ENOSYS:
+					/* No PHY support. Check if PHY is required. */
+					if (of_find_property(dev->of_node, "phys", NULL)) {
+						dev_err(dev, "couldn't get sata-phy: ENOSYS\n");
+						goto err_out;
+					}
+				case -ENODEV:
+					/* continue normally */
+					hpriv->phys = NULL;
+					break;
+
+				default:
+					goto err_out;
+
+			}
 		}
 	}
 
@@ -291,7 +403,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
  * @host_flags: ahci host flags used in ahci_host_priv
  *
  * This function does all the usual steps needed to bring up an
- * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
+ * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
  * must be initialized / enabled before calling this.
  *
  * RETURNS:
@@ -395,7 +507,7 @@ static void ahci_host_stop(struct ata_host *host)
  * @dev: device pointer for the host
  *
  * This function does all the usual steps needed to suspend an
- * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
+ * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
  * must be disabled after calling this.
  *
  * RETURNS:
@@ -432,7 +544,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
  * @dev: device pointer for the host
  *
  * This function does all the usual steps needed to resume an ahci-platform
- * host, note any necessary resources (ie clks, phy, etc.)  must be
+ * host, note any necessary resources (ie clks, phys, etc.)  must be
  * initialized / enabled before calling this.
  *
  * RETURNS:
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 3/8] ata: libahci_platform: move port_map parameters into the AHCI structure
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406193450-17283-1-git-send-email-antoine.tenart@free-electrons.com>

This patch moves force_port_map and mask_port_map into the
ahci_host_priv structure. This allows to modify them into the AHCI
framework. This is needed by the new dt bindings representing ports as
the port_map mask is computed automatically.

Signed-off-by: Antoine T?nart <antoine.tenart@free-electrons.com>
---
 drivers/ata/ahci.h             |  6 +++---
 drivers/ata/ahci_da850.c       |  3 +--
 drivers/ata/ahci_imx.c         |  3 +--
 drivers/ata/ahci_mvebu.c       |  3 +--
 drivers/ata/ahci_platform.c    |  3 +--
 drivers/ata/ahci_st.c          |  2 +-
 drivers/ata/ahci_sunxi.c       |  2 +-
 drivers/ata/ahci_xgene.c       |  2 +-
 drivers/ata/libahci.c          | 17 +++++++----------
 drivers/ata/libahci_platform.c |  8 ++------
 include/linux/ahci_platform.h  |  4 +---
 11 files changed, 20 insertions(+), 33 deletions(-)

diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 5513296e5e2e..cb8d58926851 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -321,6 +321,8 @@ struct ahci_host_priv {
 	u32			cap;		/* cap to use */
 	u32			cap2;		/* cap2 to use */
 	u32			port_map;	/* port map to use */
+	u32			force_port_map;	/* force port map */
+	u32			mask_port_map;	/* mask out particular bits */
 	u32			saved_cap;	/* saved initial cap */
 	u32			saved_cap2;	/* saved initial cap2 */
 	u32			saved_port_map;	/* saved initial port_map */
@@ -361,9 +363,7 @@ unsigned int ahci_dev_classify(struct ata_port *ap);
 void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
 			u32 opts);
 void ahci_save_initial_config(struct device *dev,
-			      struct ahci_host_priv *hpriv,
-			      unsigned int force_port_map,
-			      unsigned int mask_port_map);
+			      struct ahci_host_priv *hpriv);
 void ahci_init_controller(struct ata_host *host);
 int ahci_reset_controller(struct ata_host *host);
 
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 2b77d53bccf8..33b862b2c5db 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -85,8 +85,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
 
 	da850_sata_init(dev, pwrdn_reg, hpriv->mmio);
 
-	rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info,
-				     0, 0, 0);
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info, 0);
 	if (rc)
 		goto disable_resources;
 
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index cac4360f272a..c8eef2d745d8 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -454,8 +454,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
 	reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
 	writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
 
-	ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
-				      0, 0, 0);
+	ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0);
 	if (ret)
 		goto disable_sata;
 
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c
index fd3dfd733b84..0ba0cf7a9ba9 100644
--- a/drivers/ata/ahci_mvebu.c
+++ b/drivers/ata/ahci_mvebu.c
@@ -88,8 +88,7 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
 	ahci_mvebu_mbus_config(hpriv, dram);
 	ahci_mvebu_regret_option(hpriv);
 
-	rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info,
-				     0, 0, 0);
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info, 0);
 	if (rc)
 		goto disable_resources;
 
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index b10d81ddb528..95f9ca82082a 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -60,8 +60,7 @@ static int ahci_probe(struct platform_device *pdev)
 	if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
 		hflags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
 
-	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
-				     hflags, 0, 0);
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, hflags);
 	if (rc)
 		goto pdata_exit;
 
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c
index 2595598df9ce..6767c7790b4a 100644
--- a/drivers/ata/ahci_st.c
+++ b/drivers/ata/ahci_st.c
@@ -166,7 +166,7 @@ static int st_ahci_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
-	err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, 0, 0, 0);
+	err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, 0);
 	if (err) {
 		ahci_platform_disable_resources(hpriv);
 		return err;
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
index 02002f125bd4..9f8ff1f9e912 100644
--- a/drivers/ata/ahci_sunxi.c
+++ b/drivers/ata/ahci_sunxi.c
@@ -188,7 +188,7 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
 		 AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
 
 	rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info,
-				     hflags, 0, 0);
+				     hflags);
 	if (rc)
 		goto disable_resources;
 
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index ee3a3659bd9e..87d39fbe616b 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -487,7 +487,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
 	hflags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
 
 	rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info,
-				     hflags, 0, 0);
+				     hflags);
 	if (rc)
 		goto disable_resources;
 
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index d72ce0470309..3c0b623747bd 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -398,10 +398,7 @@ static ssize_t ahci_show_em_supported(struct device *dev,
  *	LOCKING:
  *	None.
  */
-void ahci_save_initial_config(struct device *dev,
-			      struct ahci_host_priv *hpriv,
-			      unsigned int force_port_map,
-			      unsigned int mask_port_map)
+void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
 {
 	void __iomem *mmio = hpriv->mmio;
 	u32 cap, cap2, vers, port_map;
@@ -468,17 +465,17 @@ void ahci_save_initial_config(struct device *dev,
 		cap &= ~HOST_CAP_FBS;
 	}
 
-	if (force_port_map && port_map != force_port_map) {
+	if (hpriv->force_port_map && port_map != hpriv->force_port_map) {
 		dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
-			 port_map, force_port_map);
-		port_map = force_port_map;
+			 port_map, hpriv->force_port_map);
+		port_map = hpriv->force_port_map;
 	}
 
-	if (mask_port_map) {
+	if (hpriv->mask_port_map) {
 		dev_warn(dev, "masking port_map 0x%x -> 0x%x\n",
 			port_map,
-			port_map & mask_port_map);
-		port_map &= mask_port_map;
+			port_map & hpriv->mask_port_map);
+		port_map &= hpriv->mask_port_map;
 	}
 
 	/* cross check port_map and cap.n_ports */
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index b0077589f065..db9b90d876dd 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -289,8 +289,6 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
  * @hpriv: ahci-host private data for the host
  * @pi_template: template for the ata_port_info to use
  * @host_flags: ahci host flags used in ahci_host_priv
- * @force_port_map: param passed to ahci_save_initial_config
- * @mask_port_map: param passed to ahci_save_initial_config
  *
  * This function does all the usual steps needed to bring up an
  * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
@@ -302,9 +300,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
 int ahci_platform_init_host(struct platform_device *pdev,
 			    struct ahci_host_priv *hpriv,
 			    const struct ata_port_info *pi_template,
-			    unsigned long host_flags,
-			    unsigned int force_port_map,
-			    unsigned int mask_port_map)
+			    unsigned long host_flags)
 {
 	struct device *dev = &pdev->dev;
 	struct ata_port_info pi = *pi_template;
@@ -322,7 +318,7 @@ int ahci_platform_init_host(struct platform_device *pdev,
 	pi.private_data = (void *)host_flags;
 	hpriv->flags |= host_flags;
 
-	ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
+	ahci_save_initial_config(dev, hpriv);
 
 	if (hpriv->cap & HOST_CAP_NCQ)
 		pi.flags |= ATA_FLAG_NCQ;
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 6dfd51a04d77..554bcafa7eb4 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -44,9 +44,7 @@ struct ahci_host_priv *ahci_platform_get_resources(
 int ahci_platform_init_host(struct platform_device *pdev,
 			    struct ahci_host_priv *hpriv,
 			    const struct ata_port_info *pi_template,
-			    unsigned long host_flags,
-			    unsigned int force_port_map,
-			    unsigned int mask_port_map);
+			    unsigned long host_flags);
 
 int ahci_platform_suspend_host(struct device *dev);
 int ahci_platform_resume_host(struct device *dev);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 2/8] Documentation: bindings: add the Berlin SATA PHY
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406193450-17283-1-git-send-email-antoine.tenart@free-electrons.com>

The Berlin SATA PHY drives the PHY related to the SATA interface. Add
the corresponding documentation.

Signed-off-by: Antoine T?nart <antoine.tenart@free-electrons.com>
---
 .../devicetree/bindings/phy/berlin-sata-phy.txt    | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/berlin-sata-phy.txt

diff --git a/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt b/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt
new file mode 100644
index 000000000000..cda4a100b00f
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt
@@ -0,0 +1,34 @@
+Berlin SATA PHY
+---------------
+
+Required properties:
+- compatible: should be "marvell,berlin2q-sata-phy"
+- #address-cells: should be 1
+- #size-cells: should be 0
+- #phy-cells: from the generic PHY bindings, must be 1
+- reg: address and length of the register
+- clocks: reference to the clock entry
+
+Sub-nodes:
+Each PHY should be represented as a sub-node.
+
+Sub-nodes required properties:
+- reg: the PHY number
+
+Example:
+	sata_phy: phy at f7e900a0 {
+		compatible = "marvell,berlin2q-sata-phy";
+		reg = <0xf7e900a0 0x200>;
+		clocks = <&chip CLKID_SATA>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#phy-cells = <1>;
+
+		sata-phy at 0 {
+			reg = <0>;
+		};
+
+		sata-phy at 1 {
+			reg = <1>;
+		};
+	};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 1/8] phy: add a driver for the Berlin SATA PHY
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406193450-17283-1-git-send-email-antoine.tenart@free-electrons.com>

The Berlin SoC has a two SATA ports. Add a PHY driver to handle them.

The mode selection can let us think this PHY can be configured to fit
other purposes. But there are reasons to think the SATA mode will be
the only one usable: the PHY registers are only accessible indirectly
through two registers in the SATA range, the PHY seems to be integrated
and no information tells us the contrary. For these reasons, make the
driver a SATA PHY driver.

Signed-off-by: Antoine T?nart <antoine.tenart@free-electrons.com>
---
 drivers/phy/Kconfig           |   7 ++
 drivers/phy/Makefile          |   1 +
 drivers/phy/phy-berlin-sata.c | 284 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 292 insertions(+)
 create mode 100644 drivers/phy/phy-berlin-sata.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 64b98d242ea6..458b15ae2e81 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -15,6 +15,13 @@ config GENERIC_PHY
 	  phy users can obtain reference to the PHY. All the users of this
 	  framework should select this config.
 
+config PHY_BERLIN_SATA
+	tristate "Marvell Berlin SATA PHY driver"
+	depends on ARCH_BERLIN && HAS_IOMEM && OF
+	select GENERIC_PHY
+	help
+	  Enable this to support the SATA PHY on Marvell Berlin SoCs.
+
 config PHY_EXYNOS_MIPI_VIDEO
 	tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
 	depends on HAS_IOMEM
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index b4f1d5770601..a137a2e23218 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_GENERIC_PHY)		+= phy-core.o
+obj-$(CONFIG_PHY_BERLIN_SATA)		+= phy-berlin-sata.o
 obj-$(CONFIG_BCM_KONA_USB2_PHY)		+= phy-bcm-kona-usb2.o
 obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)	+= phy-exynos-dp-video.o
 obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c
new file mode 100644
index 000000000000..c5e688b0899f
--- /dev/null
+++ b/drivers/phy/phy-berlin-sata.c
@@ -0,0 +1,284 @@
+/*
+ * Marvell Berlin SATA PHY driver
+ *
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine T?nart <antoine.tenart@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/module.h>
+#include <linux/phy/phy.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#define HOST_VSA_ADDR		0x0
+#define HOST_VSA_DATA		0x4
+#define PORT_SCR_CTL		0x2c
+#define PORT_VSR_ADDR		0x78
+#define PORT_VSR_DATA		0x7c
+
+#define CONTROL_REGISTER	0x0
+#define MBUS_SIZE_CONTROL	0x4
+
+#define POWER_DOWN_PHY0			BIT(6)
+#define POWER_DOWN_PHY1			BIT(14)
+#define MBUS_WRITE_REQUEST_SIZE_128	(BIT(2) << 16)
+#define MBUS_READ_REQUEST_SIZE_128	(BIT(2) << 19)
+
+#define PHY_BASE		0x200
+
+/* register 0x01 */
+#define REF_FREF_SEL_25		BIT(0)
+#define PHY_MODE_SATA		(0x0 << 5)
+
+/* register 0x02 */
+#define USE_MAX_PLL_RATE	BIT(12)
+
+/* register 0x23 */
+#define DATA_BIT_WIDTH_10	(0x0 << 10)
+#define DATA_BIT_WIDTH_20	(0x1 << 10)
+#define DATA_BIT_WIDTH_40	(0x2 << 10)
+
+/* register 0x25 */
+#define PHY_GEN_MAX_1_5		(0x0 << 10)
+#define PHY_GEN_MAX_3_0		(0x1 << 10)
+#define PHY_GEN_MAX_6_0		(0x2 << 10)
+
+struct phy_berlin_desc {
+	struct phy	*phy;
+	u32		power_bit;
+	unsigned	index;
+};
+
+struct phy_berlin_priv {
+	void __iomem		*base;
+	spinlock_t		lock;
+	struct clk		*clk;
+	struct phy_berlin_desc	**phys;
+	unsigned		nphys;
+};
+
+static inline void phy_berlin_sata_reg_setbits(void __iomem *ctrl_reg, u32 reg,
+					       u32 mask, u32 val)
+{
+	u32 regval;
+
+	/* select register */
+	writel(PHY_BASE + reg, ctrl_reg + PORT_VSR_ADDR);
+
+	/* set bits */
+	regval = readl(ctrl_reg + PORT_VSR_DATA);
+	regval &= ~mask;
+	regval |= val;
+	writel(regval, ctrl_reg + PORT_VSR_DATA);
+}
+
+static int phy_berlin_sata_power_on(struct phy *phy)
+{
+	struct phy_berlin_desc *desc = phy_get_drvdata(phy);
+	struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent);
+	void __iomem *ctrl_reg = priv->base + 0x60 + (desc->index * 0x80);
+	int ret = 0;
+	u32 regval;
+
+	clk_prepare_enable(priv->clk);
+
+	spin_lock(&priv->lock);
+
+	/* Power on PHY */
+	writel(CONTROL_REGISTER, priv->base + HOST_VSA_ADDR);
+	regval = readl(priv->base + HOST_VSA_DATA);
+	regval &= ~desc->power_bit;
+	writel(regval, priv->base + HOST_VSA_DATA);
+
+	/* Configure MBus */
+	writel(MBUS_SIZE_CONTROL, priv->base + HOST_VSA_ADDR);
+	regval = readl(priv->base + HOST_VSA_DATA);
+	regval |= MBUS_WRITE_REQUEST_SIZE_128 | MBUS_READ_REQUEST_SIZE_128;
+	writel(regval, priv->base + HOST_VSA_DATA);
+
+	/* set PHY mode and ref freq to 25 MHz */
+	phy_berlin_sata_reg_setbits(ctrl_reg, 0x1, 0xff,
+				    REF_FREF_SEL_25 | PHY_MODE_SATA);
+
+	/* set PHY up to 6 Gbps */
+	phy_berlin_sata_reg_setbits(ctrl_reg, 0x25, 0xc00, PHY_GEN_MAX_6_0);
+
+	/* set 40 bits width */
+	phy_berlin_sata_reg_setbits(ctrl_reg, 0x23,  0xc00, DATA_BIT_WIDTH_40);
+
+	/* use max pll rate */
+	phy_berlin_sata_reg_setbits(ctrl_reg, 0x2, 0x0, USE_MAX_PLL_RATE);
+
+	/* set Gen3 controller speed */
+	regval = readl(ctrl_reg + PORT_SCR_CTL);
+	regval &= ~GENMASK(7, 4);
+	regval |= 0x30;
+	writel(regval, ctrl_reg + PORT_SCR_CTL);
+
+	spin_unlock(&priv->lock);
+
+	clk_disable_unprepare(priv->clk);
+
+	return ret;
+}
+
+static int phy_berlin_sata_power_off(struct phy *phy)
+{
+	struct phy_berlin_desc *desc = phy_get_drvdata(phy);
+	struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent);
+	u32 regval;
+
+	clk_prepare_enable(priv->clk);
+
+	spin_lock(&priv->lock);
+
+	/* Power down PHY */
+	writel(CONTROL_REGISTER, priv->base + HOST_VSA_ADDR);
+	regval = readl(priv->base + HOST_VSA_DATA);
+	regval |= desc->power_bit;
+	writel(regval, priv->base + HOST_VSA_DATA);
+
+	spin_unlock(&priv->lock);
+
+	clk_disable_unprepare(priv->clk);
+
+	return 0;
+}
+
+static struct phy *phy_berlin_sata_phy_xlate(struct device *dev,
+					     struct of_phandle_args *args)
+{
+	struct phy_berlin_priv *priv = dev_get_drvdata(dev);
+	int i;
+
+	if (WARN_ON(args->args[0] >= priv->nphys))
+		return ERR_PTR(-ENODEV);
+
+	for (i = 0; i < priv->nphys; i++) {
+		if (priv->phys[i]->index == args->args[0])
+			break;
+	}
+
+	if (i == priv->nphys)
+		return ERR_PTR(-ENODEV);
+
+	return priv->phys[i]->phy;
+}
+
+static struct phy_ops phy_berlin_sata_ops = {
+	.power_on	= phy_berlin_sata_power_on,
+	.power_off	= phy_berlin_sata_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static u32 phy_berlin_power_down_bits[] = {
+	POWER_DOWN_PHY0,
+	POWER_DOWN_PHY1,
+};
+
+static int phy_berlin_sata_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *child;
+	struct phy *phy;
+	struct phy_provider *phy_provider;
+	struct phy_berlin_priv *priv;
+	struct resource *res;
+	int i = 0;
+	u32 phy_id;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -EINVAL;
+
+	priv->base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!priv->base)
+		return -ENOMEM;
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
+	priv->nphys = of_get_child_count(dev->of_node);
+	if (priv->nphys == 0)
+		return -ENODEV;
+
+	priv->phys = devm_kzalloc(dev, priv->nphys * sizeof(*priv->phys),
+				  GFP_KERNEL);
+	if (!priv->phys)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, priv);
+	spin_lock_init(&priv->lock);
+
+	for_each_available_child_of_node(dev->of_node, child) {
+		struct phy_berlin_desc *phy_desc;
+
+		if (of_property_read_u32(child, "reg", &phy_id)) {
+			dev_err(dev, "missing reg property in node %s\n",
+				child->name);
+			return -EINVAL;
+		}
+
+		if (phy_id >= ARRAY_SIZE(phy_berlin_power_down_bits)) {
+			dev_err(dev, "invalid reg in node %s\n", child->name);
+			return -EINVAL;
+		}
+
+		phy_desc = devm_kzalloc(dev, sizeof(*phy_desc), GFP_KERNEL);
+		if (!phy_desc)
+			return -ENOMEM;
+
+		phy = devm_phy_create(dev, &phy_berlin_sata_ops, NULL);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create PHY %d\n", phy_id);
+			return PTR_ERR(phy);
+		}
+
+		phy_desc->phy = phy;
+		phy_desc->power_bit = phy_berlin_power_down_bits[phy_id];
+		phy_desc->index = phy_id;
+		phy_set_drvdata(phy, phy_desc);
+
+		priv->phys[i++] = phy_desc;
+
+		/* Make sure the PHY is off */
+		phy_berlin_sata_power_off(phy);
+	}
+
+	phy_provider =
+		devm_of_phy_provider_register(dev, phy_berlin_sata_phy_xlate);
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
+
+	return 0;
+}
+
+static const struct of_device_id phy_berlin_sata_of_match[] = {
+	{ .compatible = "marvell,berlin2q-sata-phy" },
+	{ },
+};
+
+static struct platform_driver phy_berlin_sata_driver = {
+	.probe	= phy_berlin_sata_probe,
+	.driver	= {
+		.name		= "phy-berlin-sata",
+		.owner		= THIS_MODULE,
+		.of_match_table	= phy_berlin_sata_of_match,
+	},
+};
+module_platform_driver(phy_berlin_sata_driver);
+
+MODULE_DESCRIPTION("Marvell Berlin SATA PHY driver");
+MODULE_AUTHOR("Antoine T?nart <antoine.tenart@free-electrons.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* [PATCH v11 0/8] ARM: berlin: add AHCI support
From: Antoine Ténart @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel

Changes since v10:
	- made a 1:1 relation between PHYs and ports numbers
	- added a SoC specific compatible when using 'generic-ahci'

Changes since v9:
        - moved port_map parameters into the AHCI structure

Changes since v8:
        - stopped reset the controller from the PHY driver
        - removed fixed array sizes
        - got rid of the custom to_berlin_sata_phy_priv() macro
        - added dependency to HAS_IOMEM

Changes since v7:
        - got back to the each PHY as a sub-node representation
        - renamed the power bit in the PHY driver

Changes since v6:
        - added the 'clocks' property and support in the PHY driver
        - updated the PHY compatible

Changes since v5:
        - rebased on top of v3.16-rc1
        - added the 'clocks' property in the sata node

Changes since v4:
        - updated PHY driver as tristate
        - handled the case were no SATA port is enabled
        - updated the compatible to a generic one
        - cosmetic fixups

Changes since v3:
        - moved all PHY operations to the PHY driver
        - removed PHY sub-nodes
        - removed the custom Berlin AHCI driver and switched to
          ahci_platform
        - added multiple PHYs support to the libahci_platform

Changes since v2:
        - modeled each PHY as a sub-node
        - cosmetic fixups

Changes since v1:
        - added a PHY driver, allowing to enable each port
          individually and removed the 'force-port-map' property
        - made the drivers a bit less magic :)
        - wrote a function to select and configure registers in the
          AHCI driver
        - removed BG2 / BG2CD nodes

Antoine T?nart (8):
  phy: add a driver for the Berlin SATA PHY
  Documentation: bindings: add the Berlin SATA PHY
  ata: libahci_platform: move port_map parameters into the AHCI
    structure
  ata: libahci: allow to use multiple PHYs
  ata: ahci_platform: add a generic AHCI compatible
  Documentation: bindings: document the sub-nodes AHCI bindings
  ARM: berlin: add the AHCI node for the BG2Q
  ARM: berlin: enable the eSATA interface on the BG2Q DMP

 .../devicetree/bindings/ata/ahci-platform.txt      |  41 +++
 .../devicetree/bindings/phy/berlin-sata-phy.txt    |  34 +++
 arch/arm/boot/dts/berlin2q-marvell-dmp.dts         |   8 +
 arch/arm/boot/dts/berlin2q.dtsi                    |  39 +++
 drivers/ata/ahci.h                                 |  13 +-
 drivers/ata/ahci_da850.c                           |   3 +-
 drivers/ata/ahci_imx.c                             |   3 +-
 drivers/ata/ahci_mvebu.c                           |   3 +-
 drivers/ata/ahci_platform.c                        |   5 +-
 drivers/ata/ahci_st.c                              |   2 +-
 drivers/ata/ahci_sunxi.c                           |   2 +-
 drivers/ata/ahci_xgene.c                           |   2 +-
 drivers/ata/libahci.c                              |  17 +-
 drivers/ata/libahci_platform.c                     | 198 ++++++++++----
 drivers/phy/Kconfig                                |   7 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-berlin-sata.c                      | 284 +++++++++++++++++++++
 include/linux/ahci_platform.h                      |   4 +-
 18 files changed, 593 insertions(+), 73 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/berlin-sata-phy.txt
 create mode 100644 drivers/phy/phy-berlin-sata.c

-- 
1.9.1

^ permalink raw reply

* [PATCHv3 12/16] cpuidle: mvebu: add Armada 370 support
From: Daniel Lezcano @ 2014-07-24  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406120453-29291-13-git-send-email-thomas.petazzoni@free-electrons.com>

On 07/23/2014 03:00 PM, Thomas Petazzoni wrote:
> This commit adds the list of cpuidle states supported by the Armada
> 370 SoC in the cpuidle-mvebu-v7 driver, as well as the necessary logic
> around it to support this SoC.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   drivers/cpuidle/cpuidle-mvebu-v7.c | 35 +++++++++++++++++++++++++++++++++--
>   1 file changed, 33 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
> index 7252fd8..d23597f 100644
> --- a/drivers/cpuidle/cpuidle-mvebu-v7.c
> +++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
> @@ -70,11 +70,32 @@ static struct cpuidle_driver armadaxp_idle_driver = {
>   	.state_count = 3,
>   };
>
> +static struct cpuidle_driver armada370_idle_driver = {
> +	.name			= "armada_370_idle",
> +	.states[0]		= ARM_CPUIDLE_WFI_STATE,
> +	.states[1]		= {
> +		.enter			= mvebu_v7_enter_idle,
> +		.exit_latency		= 100,
> +		.power_usage		= 5,
> +		.target_residency	= 1000,
> +		.flags			= (CPUIDLE_FLAG_TIME_VALID |
> +					   MVEBU_V7_FLAG_DEEP_IDLE),
> +		.name			= "Deep Idle",
> +		.desc			= "CPU and L2 Fabric power down",
> +	},
> +	.state_count = 2,
> +};
> +
>   static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
>   {
> -
>   	mvebu_v7_cpu_suspend = pdev->dev.platform_data;
> -	return cpuidle_register(&armadaxp_idle_driver, NULL);
> +
> +	if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-xp"))
> +		return cpuidle_register(&armadaxp_idle_driver, NULL);
> +	else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-370"))
> +		return cpuidle_register(&armada370_idle_driver, NULL);
> +	else
> +		return -EINVAL;
>   }
>
>   static struct platform_driver armadaxp_cpuidle_plat_driver = {
> @@ -87,6 +108,16 @@ static struct platform_driver armadaxp_cpuidle_plat_driver = {
>
>   module_platform_driver(armadaxp_cpuidle_plat_driver);
>
> +static struct platform_driver armada370_cpuidle_plat_driver = {
> +	.driver = {
> +		.name = "cpuidle-armada-370",
> +		.owner = THIS_MODULE,
> +	},
> +	.probe = mvebu_v7_cpuidle_probe,
> +};
> +
> +module_platform_driver(armada370_cpuidle_plat_driver);
> +
>   MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
>   MODULE_DESCRIPTION("Marvell EBU v7 cpuidle driver");
>   MODULE_LICENSE("GPL");
>


-- 
  <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

^ permalink raw reply

* [PATCHv3 11/16] cpuidle: mvebu: rename the driver from armada-370-xp to mvebu-v7
From: Daniel Lezcano @ 2014-07-24  9:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1406120453-29291-12-git-send-email-thomas.petazzoni@free-electrons.com>

On 07/23/2014 03:00 PM, Thomas Petazzoni wrote:
> From: Gregory CLEMENT <gregory.clement@free-electrons.com>
>
> This driver will be able to manage the cpuidle for more SoCs than just
> Armada 370 and XP. It will also support Armada 38x and potentially
> other SoC of the Marvell Armada EBU family. To take this into account,
> this patch renames the driver and its symbols.
>
> It also changes the driver name from cpuidle-armada-370-xp to
> cpuidle-armada-xp, because separate platform drivers will be
> registered for the other SoC types. This change must be done
> simultaneously in the cpuidle driver and in the PMSU code in order to
> remain bisectable.
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   arch/arm/mach-mvebu/pmsu.c                         |  2 +-
>   drivers/cpuidle/Kconfig.arm                        | 12 +++----
>   drivers/cpuidle/Makefile                           |  2 +-
>   ...{cpuidle-armada-370-xp.c => cpuidle-mvebu-v7.c} | 39 +++++++++++-----------
>   4 files changed, 27 insertions(+), 28 deletions(-)
>   rename drivers/cpuidle/{cpuidle-armada-370-xp.c => cpuidle-mvebu-v7.c} (58%)
>
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index 15e67bf..0cd2d09 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -76,7 +76,7 @@ extern void armada_370_xp_cpu_resume(void);
>   static void *mvebu_cpu_resume;
>
>   static struct platform_device mvebu_v7_cpuidle_device = {
> -	.name = "cpuidle-armada-370-xp",
> +	.name = "cpuidle-armada-xp",
>   };
>
>   static struct of_device_id of_pmsu_table[] = {
> diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
> index b6d69e8..a563427 100644
> --- a/drivers/cpuidle/Kconfig.arm
> +++ b/drivers/cpuidle/Kconfig.arm
> @@ -1,12 +1,6 @@
>   #
>   # ARM CPU Idle drivers
>   #
> -config ARM_ARMADA_370_XP_CPUIDLE
> -	bool "CPU Idle Driver for Armada 370/XP family processors"
> -	depends on ARCH_MVEBU
> -	help
> -	  Select this to enable cpuidle on Armada 370/XP processors.
> -
>   config ARM_BIG_LITTLE_CPUIDLE
>   	bool "Support for ARM big.LITTLE processors"
>   	depends on ARCH_VEXPRESS_TC2_PM
> @@ -61,3 +55,9 @@ config ARM_EXYNOS_CPUIDLE
>   	depends on ARCH_EXYNOS
>   	help
>   	  Select this to enable cpuidle for Exynos processors
> +
> +config ARM_MVEBU_V7_CPUIDLE
> +	bool "CPU Idle Driver for mvebu v7 family processors"
> +	depends on ARCH_MVEBU
> +	help
> +	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index d8bb1ff..11edb31 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -7,7 +7,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
>
>   ##################################################################################
>   # ARM SoC drivers
> -obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o
> +obj-$(CONFIG_ARM_MVEBU_V7_CPUIDLE) += cpuidle-mvebu-v7.o
>   obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE)	+= cpuidle-big_little.o
>   obj-$(CONFIG_ARM_CLPS711X_CPUIDLE)	+= cpuidle-clps711x.o
>   obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE)	+= cpuidle-calxeda.o
> diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
> similarity index 58%
> rename from drivers/cpuidle/cpuidle-armada-370-xp.c
> rename to drivers/cpuidle/cpuidle-mvebu-v7.c
> index 28587d0..7252fd8 100644
> --- a/drivers/cpuidle/cpuidle-armada-370-xp.c
> +++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
> @@ -21,12 +21,11 @@
>   #include <linux/platform_device.h>
>   #include <asm/cpuidle.h>
>
> -#define ARMADA_370_XP_MAX_STATES	3
> -#define ARMADA_370_XP_FLAG_DEEP_IDLE	0x10000
> +#define MVEBU_V7_FLAG_DEEP_IDLE	0x10000
>
> -static int (*armada_370_xp_cpu_suspend)(int);
> +static int (*mvebu_v7_cpu_suspend)(int);
>
> -static int armada_370_xp_enter_idle(struct cpuidle_device *dev,
> +static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
>   				struct cpuidle_driver *drv,
>   				int index)
>   {
> @@ -34,10 +33,10 @@ static int armada_370_xp_enter_idle(struct cpuidle_device *dev,
>   	bool deepidle = false;
>   	cpu_pm_enter();
>
> -	if (drv->states[index].flags & ARMADA_370_XP_FLAG_DEEP_IDLE)
> +	if (drv->states[index].flags & MVEBU_V7_FLAG_DEEP_IDLE)
>   		deepidle = true;
>
> -	ret = armada_370_xp_cpu_suspend(deepidle);
> +	ret = mvebu_v7_cpu_suspend(deepidle);
>   	if (ret)
>   		return ret;
>
> @@ -46,11 +45,11 @@ static int armada_370_xp_enter_idle(struct cpuidle_device *dev,
>   	return index;
>   }
>
> -static struct cpuidle_driver armada_370_xp_idle_driver = {
> -	.name			= "armada_370_xp_idle",
> +static struct cpuidle_driver armadaxp_idle_driver = {
> +	.name			= "armada_xp_idle",
>   	.states[0]		= ARM_CPUIDLE_WFI_STATE,
>   	.states[1]		= {
> -		.enter			= armada_370_xp_enter_idle,
> +		.enter			= mvebu_v7_enter_idle,
>   		.exit_latency		= 10,
>   		.power_usage		= 50,
>   		.target_residency	= 100,
> @@ -59,35 +58,35 @@ static struct cpuidle_driver armada_370_xp_idle_driver = {
>   		.desc			= "CPU power down",
>   	},
>   	.states[2]		= {
> -		.enter			= armada_370_xp_enter_idle,
> +		.enter			= mvebu_v7_enter_idle,
>   		.exit_latency		= 100,
>   		.power_usage		= 5,
>   		.target_residency	= 1000,
>   		.flags			= CPUIDLE_FLAG_TIME_VALID |
> -						ARMADA_370_XP_FLAG_DEEP_IDLE,
> +						MVEBU_V7_FLAG_DEEP_IDLE,
>   		.name			= "MV CPU DEEP IDLE",
>   		.desc			= "CPU and L2 Fabric power down",
>   	},
> -	.state_count = ARMADA_370_XP_MAX_STATES,
> +	.state_count = 3,
>   };
>
> -static int armada_370_xp_cpuidle_probe(struct platform_device *pdev)
> +static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
>   {
>
> -	armada_370_xp_cpu_suspend = (void *)(pdev->dev.platform_data);
> -	return cpuidle_register(&armada_370_xp_idle_driver, NULL);
> +	mvebu_v7_cpu_suspend = pdev->dev.platform_data;
> +	return cpuidle_register(&armadaxp_idle_driver, NULL);
>   }
>
> -static struct platform_driver armada_370_xp_cpuidle_plat_driver = {
> +static struct platform_driver armadaxp_cpuidle_plat_driver = {
>   	.driver = {
> -		.name = "cpuidle-armada-370-xp",
> +		.name = "cpuidle-armada-xp",
>   		.owner = THIS_MODULE,
>   	},
> -	.probe = armada_370_xp_cpuidle_probe,
> +	.probe = mvebu_v7_cpuidle_probe,
>   };
>
> -module_platform_driver(armada_370_xp_cpuidle_plat_driver);
> +module_platform_driver(armadaxp_cpuidle_plat_driver);
>
>   MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
> -MODULE_DESCRIPTION("Armada 370/XP cpu idle driver");
> +MODULE_DESCRIPTION("Marvell EBU v7 cpuidle driver");
>   MODULE_LICENSE("GPL");
>


-- 
  <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

^ permalink raw reply

* Kexec on arm64
From: Mark Rutland @ 2014-07-24  9:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAFdej03nixSU=3h+HYk2E3Onb2P3--Di0GM+wCwLS6ZNH7UjEQ@mail.gmail.com>

[...]

> 2) Rebooting
> #########################
> # kexec -e
> kexec version: 1kvm: exiting hardware virtualization
> 4.07.17.12.17-gbStarting new kernel
> 6cccb4
>  Ump_spin_tanblaeb_lcpeu_d ite:127: oi dh:a n7d,l holding count: 0e
>  kernel NULL pointer dereference at virtual address 00000291
> smp_spin_Itnaibtlei_cpaul_diie:12z7:i nigd :c 3g,r oholding couunpt :s 0u

Hmm. This looks like two threads/CPUs are outputting characters at the
same time, something like "smp_spin_table_die" and "Initial cpu" seem to
be interspersed.

Mark.

> bsys cpu
> smpL_isnpuixn _table_cpu_diev:e1r2s7i:o ni d: 6, hol3d.i1n6g. 0c-orucnt: 0
> 4+ (arun at arun-OptiPlex-9010) (gcc version 4.9.1 20140505 (prerelease)
> (crosstool-NG linaro-1.13.1-4.9-2014.05 - Linaro GCC 4.9-2014.05) )
> #25 SMP smp_sPpin_tablReE_EcMpPuT_ dTie:127: iude:  J5u, hlo ld2ing
> coun2:
> 37:03 IST 2014
> smp_Cspin_tPabUl:e _AcApruc_die:127: id: h46,4  hPorldiong count:c e0s
>  or [500f0000] revision 0
> smp_speifni_:t aGbeltet_cpu_die:i1n2g7 : ipd:a 2, holdinrga mceount:t e0
> rs from FDT:
> smep_fsip:i nC_atable_cpu_dien:'1t27: i df: 1i, holdinngd  cSoyusntt:e 0
> m Table in device tree!
> macchimne_kexaec:: 572C: smp_pMrAo:c efsasiorl_ied = 0
> d to reserve 16 MiB
> dachine_kexecO:n5 7n4o:
>  e 0 totalpages: 4194304
> a k e xec image inNfoor:m
>  l zone: 57344 pages used for memmap
>     type:        0
> z   sta r tN:o     r  m4a0000800l04
>  one: 4194304 pages, LIFO batch:31
>     head:   P E R   43Cea9bPf002
> U: Embedded 11 pages/cpu @ffffffc3fff7d000 s13120 r8192 d23744 u45056
>     nrp_cspeug-maelnltosc: 2
> : s13120 r8192 d23744 u45056 alloc=11*4096
>    p c p usegment-[a0l]l:o c0:0 0[0000400]00 800 000[ -0 ]0000004000
> 881c 0[000],  280c000h bytes,  [200]6 0 3pages
>  [0] 4 [0] 5 [0] 6 [0] 7
> eexBeuc_is_dtb:1i1l5:t  m1a gizc: 0 : 0 : noon
>  lists in Zone order, mobility grouping on.  Total pages: 4136960
> /  K e r segment[1]: n0e0l0 00c0o400m08a0000 m-a n0d00
> 00040l008ai30n00e,:  3r000ho obty=tes, 3/ dpeagesv
>  nfs rw nfsroot=10.162.103.228:/nfs_root/dora_june_6/apm-image-minimal-mustangbe
> ip=10.162.103.21:10.162.103.228:10.162.103.1:255.255.255.0:mustangk:eextehc_0is:_odtb:1f15f:
>  pmaangic:i 0c =: 0 : 1no
> console=ttyS0,115200 earlyprintk=uart8250-32bit,0x1c020000 debug
> maxcpus=8 swiotlb=65536 log_buf_len=1M
> 8aclhinoeg_kex_ec:582: cobnturfo_ll_ecode_page:        nf:f f1ff0fbc4edb67ee8
>  576
> 6achinee_akrelxyec: 58l4: reobogo tb_ucfo dfe_buffer_physr:e e :0
> 000010435eaffb00007
>  (92%)
> macPhine_IkDexec:58 6h:a srehb otot_acode_bufferb:l e   e n t
> rfifffffce3se:a f4f0b000
> 96 (order: 3, 32768 bytes)
> macDhine_kexeecn:t5r88: ryel occate_neaw_ckheer nelh:a s     fffffhf
> c0t0a0093b18
> ble entries: 2097152 (order: 12, 16777216 bytes)
> machineI_kneoxedc:5e90-: relocate_cnaecwh_ek ehransel_size: b8hh( 1t84)a bytes
> ble entries: 1048576 (order: 11, 8388608 bytes)
> machinMe_keemxoercy::5 913: kexec6_5d0t8b_6addr2:4 K
> 0/0100004600708a0000
> 77216K available (4360K kernel code, 299K rwdata, 1528K rodata, 6556K
> init, 202K bss, 268592K reserved)
> oacVhinei_kretxueacl: 595: kexec_kkeirmnaegle _mhead:     e m o r0y0
> 00l0043eaa9bf002y
>  ut:
>     vmalloc : 0xffffff8000000000 - 0xffffffbbffff0000   (245759 MB)
>     vmemmap : 0xffffffbce0000000 - 0xffffffbcee000000   (   224 MB)
> 0  machine_ kmeoxdecu:l597:e kexecs_ k:i m0age_xsftarft:    f  f
> f0f0b0f0f0c04000080004
>  00000 - 0xffffffc000000000   (    64 MB)
>     memory  : 0xffffffc000000000 - 0xffffffc400000000   ( 16384 MB)
>       .init : 0xffffffc000642000 -machine_ke x0excf:f5f99:f
> kexec_efntfrcy0_0d0ump:
> ca9340   (  6557 kB)
>       .text : 0xffffffc000080000 - 0xffffffc0006411c4   (  5893 kB)
> f     .data : 0xffffffc000caa000 - 0xffffffc000cf4f28     (I
> 43ea9bf002 =  343ea9b0f000 (f0fffffc 3ekaB9)b
>  000)
> d D 40S0LU00B8:0 0H0W1 = a4000080000l i(gfnf=f6f4ffc,00008000 0O)r
> ######################
> 
> This doesn't seems to be working. Random behaviors are observed. Some
> times it rebooted to u-boot
> prompt. Sometimes kernel soft resets itself in an endless loop
> (bootlog is repeating over and over again)
> 
> To debug what is happening I put a while(1) just before jumping into
> kexec reboot code.
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 31cba91..8843623 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -85,6 +85,7 @@ void soft_restart(unsigned long addr)
> 
>         smp_secondary_shutdown();
> 
> +       while(1);
>         /* Switch to the identity mapping */
>         phys_reset = (phys_reset_t)virt_to_phys(cpu_reset);
>         phys_reset(addr);
> 
> I break into target with BDI3000 now; and see the below output
> 
> TARGET#0>state
> Core#0: halted 0xffffffc000085240 External Debug Request
> Core#1: halted 0x0000004000080394 External Debug Request
> Core#2: halted 0x0000004000080394 External Debug Request
> Core#3: halted 0x0000004000080394 External Debug Request
> Core#4: halted 0xffffffc0000802f8 External Debug Request
> Core#5: halted 0x0000004000080394 External Debug Request
> Core#6: halted 0xffffffc0000802f8 External Debug Request
> Core#7: halted 0x0000004000080394 External Debug Request
> 
> I think some of the secondary CPUs are not behaving as expected;
> As of now I don't have any clues for this.
> 
> 
> --Arun
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* [PATCH] cpufreq: Don't destroy/realloc policy/sysfs on hotplug/suspend
From: skannan at codeaurora.org @ 2014-07-24  9:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKohpokynnTttD7Wbq8uBB4SXK9xFEBdRJ2ozhMQscyvq69xRw@mail.gmail.com>


Viresh Kumar wrote:
> On 24 July 2014 08:32, Saravana Kannan <skannan@codeaurora.org> wrote:
>> Ok, I think I've figured this out. But one question. Is it possible to
>> physically remove one CPU in a bunch of "related cpus" without also
>> unplugging the rest? Put another way, can you unplug one core from a
>> cluster?
>
> Are we talking about doing this here:
>
> echo 0 > /sys/devices/system/cpu/cpuX/online      ??
>
> If yes, then what's the confusion all about? Yes we do it all the time.
>

No. That's why I said physically remove.

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

^ permalink raw reply

* [PATCH v2 14/16] cpufreq: Add cpufreq driver for Tegra124
From: Thierry Reding @ 2014-07-24  9:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKohponsS8WJy4qBa=3em9AcxfpfLZR_mx4Ln8N3Q_gBaf52NA@mail.gmail.com>

On Thu, Jul 24, 2014 at 05:43:40AM +0530, Viresh Kumar wrote:
> On 24 July 2014 00:47, Tuomas Tynkkynen <ttynkkynen@nvidia.com> wrote:
> > It's this:
> >
> > +static int tegra124_cpufreq_probe(struct platform_device *pdev)
> > +{
> > [...]
> > +
> > +       dfll_clk = of_clk_get_by_name(cpu_dev->of_node, "dfll");
> > +       if (IS_ERR(dfll_clk)) {
> > +               ret = PTR_ERR(dfll_clk);
> > +               goto out_put_cpu_clk;
> > +       }
> 
> This would search for clocks passed via DT, right? Why would we
> get EPROBE_DEFER for that? Sorry for the stupid question.

of_clk_get_by_name() can return -EPROBE_DEFER, which will happen if the
clock provider hasn't been registered yet.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140724/4ff0a233/attachment.sig>

^ permalink raw reply

* [PATCH v2 1/8] dma: sun4i: Add support for the DMA engine on sun[457]i SoCs
From: Maxime Ripard @ 2014-07-24  8:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53C843DC.8090808@elopez.com.ar>

Hi,

On Thu, Jul 17, 2014 at 06:45:00PM -0300, Emilio L?pez wrote:
> >>+	depends on (MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || (COMPILE_TEST && OF && ARM))
> >
> >This pretty much defeats the purpose of COMPILE_TEST
> 
> QCOM_BAM_DMA does it that way; it's better to get some coverage than
> none I guess?

You'll get that kind of coverage with multi_v7 already, so that looks
quite redundant.

> >>+	help
> >>+	  Enable support for the DMA controller present in the sun4i,
> >>+	  sun5i and sun7i Allwinner ARM SoCs.
> >>+
> (...)
> >>+
> >>+/** Normal DMA register values **/
> >>+
> >>+/* Normal DMA source/destination data request type values */
> >>+#define NDMA_DRQ_TYPE_SDRAM			0x16
> >>+#define NDMA_DRQ_TYPE_LIMIT			(0x1F + 1)
> >
> >Hmmm, I'm unsure what this is about... What is it supposed to do, and
> >how is it different from BIT(5) ?
> 
> if (val < NDMA_DRQ_TYPE_LIMIT)
> 	/* valid value */
> else
> 	/* invalid value */
> 
> 0x1F is the last valid value

Ok.

> >>+
> >>+static void set_pchan_interrupt(struct sun4i_dma_dev *priv,
> >>+				struct sun4i_dma_pchan *pchan,
> >>+				int half, int end)
> >>+{
> >>+	u32 reg = readl_relaxed(priv->base + DMA_IRQ_ENABLE_REG);
> >>+	int pchan_number = pchan - priv->pchans;
> >>+
> >>+	if (half)
> >>+		reg |= BIT(pchan_number * 2);
> >>+	else
> >>+		reg &= ~BIT(pchan_number * 2);
> >>+
> >>+	if (end)
> >>+		reg |= BIT(pchan_number * 2 + 1);
> >>+	else
> >>+		reg &= ~BIT(pchan_number * 2 + 1);
> >>+
> >>+	writel_relaxed(reg, priv->base + DMA_IRQ_ENABLE_REG);
> >
> >I don't see any interrupts here.
> 
> Hm?

I'm not sure, but I think I meant spinlocks, it doesn't make much
sense otherwise.

> >>+	for_each_sg(sgl, sg, sg_len, i) {
> >>+		/* Figure out addresses */
> >>+		if (dir == DMA_MEM_TO_DEV) {
> >>+			srcaddr = sg_dma_address(sg);
> >>+			dstaddr = sconfig->dst_addr;
> >>+		} else {
> >>+			srcaddr = sconfig->src_addr;
> >>+			dstaddr = sg_dma_address(sg);
> >>+		}
> >>+
> >>+		/* TODO: should this be configurable? */
> >>+		para = DDMA_MAGIC_SPI_PARAMETERS;
> >
> >What is it? Is it supposed to change from one client device to
> >another?
> 
> These are the magic DMA engine timings that keep SPI going. I
> haven't seen any interface on DMAEngine to configure timings, and so
> far they seem to work for everything we support, so I've kept them
> here. I don't know if other devices need different timings because,
> as usual, we only have the "para" bitfield meanings, but no comment
> on what the values should be when doing a certain operation :|

If it works for everything you tested so far, I guess you can leave it
that way, only adding what you just replied to the TODO.

> >>+static enum dma_status sun4i_dma_tx_status(struct dma_chan *chan,
> >>+					   dma_cookie_t cookie,
> >>+					   struct dma_tx_state *state)
> >>+{
> >>+	struct sun4i_dma_vchan *vchan = to_sun4i_dma_vchan(chan);
> >>+	struct sun4i_dma_pchan *pchan = vchan->pchan;
> >>+	struct sun4i_dma_contract *contract;
> >>+	struct sun4i_dma_promise *promise;
> >>+	struct virt_dma_desc *vd;
> >>+	unsigned long flags;
> >>+	enum dma_status ret;
> >>+	size_t bytes = 0;
> >>+
> >>+	ret = dma_cookie_status(chan, cookie, state);
> >>+	if (ret == DMA_COMPLETE)
> >>+		return ret;
> >>+
> >>+	spin_lock_irqsave(&vchan->vc.lock, flags);
> >>+	vd = vchan_find_desc(&vchan->vc, cookie);
> >>+	if (!vd) /* TODO */
> >
> >TODO what?
> >
> 
> /* TODO: remove the TODO */

:)

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/20140724/1d013a68/attachment.sig>

^ permalink raw reply

* next build: 629 warnings 1 failures (next/next-20140723)
From: Will Deacon @ 2014-07-24  8:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOesGMhT9n7nVbCay5cU74pv2qrbqMooZLoY923Lk6SzXk5z+A@mail.gmail.com>

On Thu, Jul 24, 2014 at 12:27:30AM +0100, Olof Johansson wrote:
> On Wed, Jul 23, 2014 at 2:40 AM, Olof's autobuilder <build@lixom.net> wrote:
> >         arm64.defconfig:
> > arch/arm64/kernel/head.S:298: Error: unknown or missing system register name at operand 2 -- `mrs x0,S3_4_C12_C9_5'
> > arch/arm64/kernel/head.S:301: Error: unknown or missing system register name at operand 1 -- `msr S3_4_C12_C9_5,x0'
> > arch/arm64/kernel/head.S:303: Error: unknown or missing system register name at operand 1 -- `msr S3_4_C12_C11_0,xzr'
> > arch/arm64/kernel/ptrace.c:1119:3: error: too many arguments to function 'audit_syscall_entry'
> > /tmp/ccq7ZztI.s:21: Error: unknown or missing system register name at operand 1 -- `msr S3_0_C12_C12_1,x0'
> > /tmp/ccq7ZztI.s:162: Error: unknown or missing system register name at operand 2 -- `mrs x19,S3_0_C12_C12_0'
> > /tmp/ccq7ZztI.s:186: Error: unknown or missing system register name at operand 1 -- `msr S3_0_C12_C12_1,x19'
> > /tmp/ccq7ZztI.s:220: Error: unknown or missing system register name at operand 1 -- `msr S3_0_C12_C12_1,x19'
> > /tmp/ccq7ZztI.s:1110: Error: unknown or missing system register name at operand 1 -- `msr S3_0_C12_C11_5,x27'
> > /tmp/ccq7ZztI.s:1530: Error: unknown or missing system register name at operand 2 -- `mrs x0,S3_0_C12_C12_5'
> > /tmp/ccq7ZztI.s:1540: Error: unknown or missing system register name at operand 1 -- `msr S3_0_C12_C12_5,x0'
> > /tmp/ccq7ZztI.s:1548: Error: unknown or missing system register name at operand 2 -- `mrs x0,S3_0_C12_C12_5'
> > /tmp/ccq7ZztI.s:1564: Error: unknown or missing system register name at operand 1 -- `msr S3_0_C4_C6_0,x0'
> > /tmp/ccq7ZztI.s:1576: Error: unknown or missing system register name at operand 1 -- `msr S3_0_C12_C12_4,x0'
> > /tmp/ccq7ZztI.s:1592: Error: unknown or missing system register name at operand 1 -- `msr S3_0_C12_C12_7,x0'
> 
> 
> I'm building with a vanilla gcc 4.8.2 / binutils 2.23.2. That
> shouldn't be broken like this, so those changes should be fixed (or
> minimal toolchain expecations need to be documented -- but there
> really is no good reason to require 4.9.0/2.24).

These all come from the GICv3 driver, so it's not going to be a lot of fun
fixing them. You'd have to introduce a macro for generating the system-reg
accesses (for both C and asm), then switch the GIC driver and the arch code
over to using that.

Will

^ permalink raw reply

* [PATCH 2/3] ARM: smp_scu: enable SCU standby support
From: Shawn Guo @ 2014-07-24  8:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140723164521.GF20966@arm.com>

On Wed, Jul 23, 2014 at 05:45:21PM +0100, Catalin Marinas wrote:
> On Wed, Jul 23, 2014 at 05:50:57AM +0100, Shawn Guo wrote:
> > On Tue, Jul 22, 2014 at 05:13:31PM +0100, Catalin Marinas wrote:
> > > And we don't know the behaviour of setting this bit on such A9 early
> > > revisions. So we can try to (1) find out if there are any in the field,
> > > (2) read the RTL to see if anything happens or (3) add a check in Linux
> > > for such revisions. I think (3) should be the case but you need to figure
> > > out which revisions these are.
> > 
> > Can I ask the favor from you ARM folks on that, since I cannot figure
> > it out from any public information?
> 
> Looking through some of the older A9 TRMs, it seems that this bit was
> added in r2p0. Whether it works as advertised on the relevant SoCs I
> can't tell.

Thanks for checking, Catalin.

Shawn

^ permalink raw reply

* [[RFC PATCH]] gpio: gpio-mxc: make sure gpio is input when request IRQ
From: Markus Niebel @ 2014-07-24  8:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdYxOv+k2Sazm83sA=LwKUv5yMzag44A=Ez8pNQHRO3V6A@mail.gmail.com>

Am 23.07.2014 18:14, wrote Linus Walleij:
> On Tue, Jul 22, 2014 at 9:42 AM, Shawn Guo <shawn.guo@linaro.org> wrote:
>> On Tue, Jul 22, 2014 at 09:19:22AM +0200, Markus Niebel wrote:
> 
>>> Currently client drivers have simply interrupts and interrupt-parent
>>> in their bindings, but no interrupt-gpios. Therefore in this case a
>>> client does not know about a dedicated gpio which is to be requested
>>> and configured.
>>
>> Okay.  I understand your problem now.  This is an issue in case we
>> specify a GPIO to be used as interrupt from device tree.  In non-DT
>> world, client driver knows this is an interrupt on GPIO, and therefore
>> takes the responsibility to request and configure the GPIO to work as
>> interrupt.  But in DT case, client driver does not know whether it's an
>> IRQ line or GPIO based interrupt.  The consequence is that GPIO
>> subsystem, OF subsystem, client driver, none of the three is requesting
>> and configuring the GPIO to be used as interrupt.
>>
>> This is a common issue instead of i.MX specific, and should be addressed
>> globally, I think.
> 
> This is very well documented in Documentation/gpio/driver.txt these
> days. Quoting:
> 

Sorry for not carefully reading the docs and many thanks for the helpful comments.

> "
> It is legal for any IRQ consumer to request an IRQ from any irqchip no matter
> if that is a combined GPIO+IRQ driver. The basic premise is that gpio_chip and
> irq_chip are orthogonal, and offering their services independent of each
> other.
> 
> gpiod_to_irq() is just a convenience function to figure out the IRQ for a
> certain GPIO line and should not be relied upon to have been called before
> the IRQ is used.
> 
> So always prepare the hardware and make it ready for action in respective
> callbacks from the GPIO and irqchip APIs. Do not rely on gpiod_to_irq() having
> been called first.
> 

So a gpio driver is responsible to read status of gpio lines and flag any gpio line 
currently configured as out (base on the information read from hardware registers) 
on driver probe time - correct? If yes is the driver allowed to call 
gpiod_get_direction() to have the FLAG_IS_OUT set in the gpiolib layer?

> This orthogonality leads to ambiguities that we need to solve: if there is
> competition inside the subsystem which side is using the resource (a certain
> GPIO line and register for example) it needs to deny certain operations and
> keep track of usage inside of the gpiolib subsystem. This is why the API
> below exists.
> 
> 
> Locking IRQ usage
> -----------------
> Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
> to mark the GPIO as being used as an IRQ:
> 
>         int gpiod_lock_as_irq(struct gpio_desc *desc)
> 
> This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
> is released:
> 
>         void gpiod_unlock_as_irq(struct gpio_desc *desc)
> 
> When implementing an irqchip inside a GPIO driver, these two functions should
> typically be called in the .startup() and .shutdown() callbacks from the
> irqchip.
> "
> 
> So: make sure each API can be used orthogonally by just poking
> into the hardware registers. Do not call gpio_request_one().

Makes sense.

Thanks again

Markus

> 
> Yours,
> Linus Walleij
> --
> 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
> 

^ permalink raw reply

* [PATCH v3 2/2] pwm: rockchip: Added to support for RK3288 SoC
From: Heiko Stübner @ 2014-07-24  8:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <53D06BE3.7010509@rock-chips.com>

Hi caesar.

Am Donnerstag, 24. Juli 2014, 10:13:55 schrieb caesar:
> >> +static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip, bool
> >> enable)
> >> +{
> >> +	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
> >> +	u32 val = 0;
> >> +	u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
> >> +
> >> +	val = readl_relaxed(pc->base + pc->data->regs.ctrl);
> >> +
> >> +	if (enable)
> >> +		val |= enable_conf;
> >> +	else
> >> +		val &= ~enable_conf;
> >> +
> >> +	writel_relaxed(val, pc->base + pc->data->regs.ctrl);
> >> +}
> >> +
> >> +static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip, bool
> >> enable)
> >> +{
> >> +	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
> >> +	u32 val = 0;
> >> +	u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
> >> +		PWM_CONTINUOUS | PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
> >> +
> >> +	val = readl_relaxed(pc->base + pc->data->regs.ctrl);
> >> +
> >> +	if (enable)
> >> +		val |= enable_conf;
> >> +	else
> >> +		val &= ~enable_conf;
> >> +
> >> +	writel_relaxed(val, pc->base + pc->data->regs.ctrl);
> >> +}
> >> +
> >> +static void rockchip_pwm_set_enable_vop(struct pwm_chip *chip, bool
> >> enable) +{
> >> +	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
> >> +	u32 val = 0;
> >> +	u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
> >> +		PWM_CONTINUOUS | PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
> >> +
> >> +	val = readl_relaxed(pc->base + pc->data->regs.ctrl);
> >> +
> >> +	if (enable)
> >> +		val |= enable_conf;
> >> +	else
> >> +		val &= ~enable_conf;
> >> +
> >> +	writel_relaxed(val, pc->base + pc->data->regs.ctrl);
> >> +}
> > 
> > not sure if I'm just blind ... do rockchip_pwm_set_enable_v2 and
> > rockchip_pwm_set_enable_vop differ at all?
> > 
> > If they don't differ, I guess pwm_data_vop should just use
> > rockchip_pwm_set_enable_v2 instead of duplicating it.
> > 
> 
> Yes, the rockchip_pwm_set_enable_v1 & v2 & vop is similar.
> 
> So my v2 patch use "u32 enable_conf" instead of it .
> +struct rockchip_pwm_data {
> 
>  > + .........
>  > + u32 enable_conf;
>  > +};
> 
> The thierry has suggested it [1] in my v2 patch:
> 
> For this I think it would be more readable to provide function pointers
> rather than a variable. That is:
> 
> 	struct rockchip_pwm_data {
> 		...
> 		int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
> 		int (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
> 	};
> Then you can implement these for each variant of the chip and call them
> from the common rockchip_pwm_enable(), somewhat like this.
> 
> 
> Perhaps,thierry's suggestion I got it wrong.

Using the function pointers like Thierry suggested looks nice, so no I don't 
think you got it wrong :-)

What I meant was to simply reuse the existing function 
rockchip_pwm_set_enable_v2 when there is _no_ difference at all to 
rockchip_pwm_set_enable_vop, like

static const struct rockchip_pwm_data pwm_data_v2 = {
	.regs.duty = PWM_LRC,
	.regs.period = PWM_HRC,
	.regs.cntr = PWM_CNTR,
	.regs.ctrl = PWM_CTRL,
	.prescaler = PRESCALER-1,
	.set_enable = rockchip_pwm_set_enable_v2,
};

static const struct rockchip_pwm_data pwm_data_vop = {
	.regs.duty = PWM_LRC,
	.regs.period = PWM_HRC,
	.regs.cntr = PWM_CTRL,
	.regs.ctrl = PWM_CNTR,
	.prescaler = PRESCALER-1,
	.set_enable = rockchip_pwm_set_enable_v2,
};


Heiko

> 
> Hi thierry& Heiko :-)
> Maybe,could you suggest solve it reasonable? thanks.
> 
> [1]: https://lkml.org/lkml/2014/7/21/113
> 
> >> +
> >> 
> >>   static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device
> >> 
> >> *pwm, int duty_ns, int period_ns)
> >> 
> >>   {
> >> 
> >> @@ -52,20 +126,20 @@ static int rockchip_pwm_config(struct pwm_chip
> >> *chip,
> >> struct pwm_device *pwm, * default prescaler value for all practical clock
> >> rate values.
> >> 
> >>   	 */
> >>   	
> >>   	div = clk_rate * period_ns;
> >> 
> >> -	do_div(div, PRESCALER * NSEC_PER_SEC);
> >> +	do_div(div, pc->data->prescaler * NSEC_PER_SEC);
> >> 
> >>   	period = div;
> >>   	
> >>   	div = clk_rate * duty_ns;
> >> 
> >> -	do_div(div, PRESCALER * NSEC_PER_SEC);
> >> +	do_div(div, pc->data->prescaler * NSEC_PER_SEC);
> >> 
> >>   	duty = div;
> >>   	
> >>   	ret = clk_enable(pc->clk);
> >>   	if (ret)
> >>   	
> >>   		return ret;
> >> 
> >> -	writel(period, pc->base + PWM_LRC);
> >> -	writel(duty, pc->base + PWM_HRC);
> >> -	writel(0, pc->base + PWM_CNTR);
> >> +	writel(period, pc->base + pc->data->regs.period);
> >> +	writel(duty, pc->base + pc->data->regs.duty);
> >> +	writel(0, pc->base + pc->data->regs.cntr);
> >> 
> >>   	clk_disable(pc->clk);
> >> 
> >> @@ -76,15 +150,12 @@ static int rockchip_pwm_enable(struct pwm_chip
> >> *chip,
> >> struct pwm_device *pwm) {
> >> 
> >>   	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
> >>   	int ret;
> >> 
> >> -	u32 val;
> >> 
> >>   	ret = clk_enable(pc->clk);
> >>   	if (ret)
> >>   	
> >>   		return ret;
> >> 
> >> -	val = readl_relaxed(pc->base + PWM_CTRL);
> >> -	val |= PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
> >> -	writel_relaxed(val, pc->base + PWM_CTRL);
> >> +	pc->data->set_enable(chip, true);
> >> 
> >>   	return 0;
> >>   
> >>   }
> >> 
> >> @@ -92,11 +163,8 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
> >> struct pwm_device *pwm) static void rockchip_pwm_disable(struct pwm_chip
> >> *chip, struct pwm_device *pwm) {
> >> 
> >>   	struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
> >> 
> >> -	u32 val;
> >> 
> >> -	val = readl_relaxed(pc->base + PWM_CTRL);
> >> -	val &= ~(PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN);
> >> -	writel_relaxed(val, pc->base + PWM_CTRL);
> >> +	pc->data->set_enable(chip, false);
> >> 
> >>   	clk_disable(pc->clk);
> >>   
> >>   }
> >> 
> >> @@ -108,12 +176,52 @@ static const struct pwm_ops rockchip_pwm_ops = {
> >> 
> >>   	.owner = THIS_MODULE,
> >>   
> >>   };
> >> 
> >> +static const struct rockchip_pwm_data pwm_data_v1 = {
> >> +	.regs.duty = PWM_HRC,
> >> +	.regs.period = PWM_LRC,
> >> +	.regs.cntr = PWM_CNTR,
> >> +	.regs.ctrl = PWM_CTRL,
> >> +	.prescaler = PRESCALER,
> >> +	.set_enable = rockchip_pwm_set_enable_v1,
> >> +};
> >> +
> >> +static const struct rockchip_pwm_data pwm_data_v2 = {
> >> +	.regs.duty = PWM_LRC,
> >> +	.regs.period = PWM_HRC,
> >> +	.regs.cntr = PWM_CNTR,
> >> +	.regs.ctrl = PWM_CTRL,
> >> +	.prescaler = PRESCALER-1,
> >> +	.set_enable = rockchip_pwm_set_enable_v2,
> >> +};
> >> +
> >> +static const struct rockchip_pwm_data pwm_data_vop = {
> >> +	.regs.duty = PWM_LRC,
> >> +	.regs.period = PWM_HRC,
> >> +	.regs.cntr = PWM_CTRL,
> >> +	.regs.ctrl = PWM_CNTR,
> >> +	.prescaler = PRESCALER-1,
> >> +	.set_enable = rockchip_pwm_set_enable_vop,
> >> +};
> >> +
> >> +static const struct of_device_id rockchip_pwm_dt_ids[] = {
> >> +	{ .compatible = "rockchip,rk2928-pwm", .data = &pwm_data_v1},
> >> +	{ .compatible = "rockchip,rk3288-pwm", .data = &pwm_data_v2},
> >> +	{ .compatible = "rockchip,vop-pwm", .data = &pwm_data_vop},
> >> +	{ /* sentinel */ }
> >> +};
> >> +MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids);
> >> +
> >> 
> >>   static int rockchip_pwm_probe(struct platform_device *pdev)
> >>   {
> >> 
> >> +	const struct of_device_id *id;
> >> 
> >>   	struct rockchip_pwm_chip *pc;
> >>   	struct resource *r;
> >>   	int ret;
> >> 
> >> +	id = of_match_device(rockchip_pwm_dt_ids, &pdev->dev);
> >> +	if (!id)
> >> +		return -EINVAL;
> >> +
> >> 
> >>   	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
> >>   	if (!pc)
> >>   	
> >>   		return -ENOMEM;
> >> 
> >> @@ -133,6 +241,7 @@ static int rockchip_pwm_probe(struct platform_device
> >> *pdev)
> >> 
> >>   	platform_set_drvdata(pdev, pc);
> >> 
> >> +	pc->data = id->data;
> >> 
> >>   	pc->chip.dev = &pdev->dev;
> >>   	pc->chip.ops = &rockchip_pwm_ops;
> >>   	pc->chip.base = -1;
> >> 
> >> @@ -156,12 +265,6 @@ static int rockchip_pwm_remove(struct
> >> platform_device
> >> *pdev) return pwmchip_remove(&pc->chip);
> >> 
> >>   }
> >> 
> >> -static const struct of_device_id rockchip_pwm_dt_ids[] = {
> >> -	{ .compatible = "rockchip,rk2928-pwm" },
> >> -	{ /* sentinel */ }
> >> -};
> >> -MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids);
> >> -
> >> 
> >>   static struct platform_driver rockchip_pwm_driver = {
> >>   
> >>   	.driver = {
> >>   	
> >>   		.name = "rockchip-pwm",

^ permalink raw reply

* iMX6Q - PCIe
From: Eric Bénard @ 2014-07-24  7:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACUGKYMpgN6PY5hrzNuM3KbT2+ZZtZ8M3es8QkXLxMD_hVcEAQ@mail.gmail.com>

Hi John,

Le Wed, 23 Jul 2014 15:44:47 -0700,
John Tobias <john.tobias.ph@gmail.com> a ?crit :
> I have a few questions:
> 
> 1. May I know what FSL's kernel version you are using?.
was 3.0.35 + backport from 3.14 for 802.11 + ath9k from
http://drvbp1.linux-foundation.org/~mcgrof/rel-html/backports/

> 2. Did you make changes in your device tree for PCIe?.
no DT on this kernel

> 3. Can I have the model/part # of your ath9k?.
tested with Mikrotik R11E & Ubiquiti SR71

Eric

^ permalink raw reply

* [PATCHv4 4/5] of/mtd/nand: add generic binding and helper for NAND_BBT_NO_OOB_BBM
From: Brian Norris @ 2014-07-24  7:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140724084915.703a1fa0@ipc1.ka-ro>

On Thu, Jul 24, 2014 at 08:49:15AM +0200, Lothar Wa?mann wrote:
> Brian Norris wrote:
> > On Thu, Jun 12, 2014 at 03:20:44PM +0200, Lothar Wa?mann wrote:
> > > add a boolean property 'nand-no-oob-bbm' and helper function to be
> > > able to set the NAND_BBT_NO_OOB_BBM flag in DT capable NAND drivers
> > > and use it for i.MX and MXS nand drivers.
> > 
> > If I'm understanding your previous conversations with Huang correctly,
> > you *must* use NAND_BBT_NO_OOB_BBM if you're going to use the
> > fsl,no-blockmark-swap option. Correct? If so, then you might not need
> > a separate 'nand-no-oob-bbm' binding; your driver should imply from
> > 'fsl,no-blockmark-swap' that it must also enable NAND_BBT_NO_OOB_BBM.
> > 
> no-blockmark-swap implies NO_OOB_BBM but NO_OOB_BBM may also be used
> independent from no-blockmark-swap.

Why would you want NO_OOB_BBM without no-blockmark-swap? If the block is
bad, why do you care what's written to it? (For that matter, why is it
ever important to use NO_OOB_BBM? At worst, the extra BB marks are
useless / written to the wrong place.)

> IMO writing a bad block marker to flash (which is prevented by
> the NAND_BBT_NO_OOB_BBM flag) is a misinterpretation of the purpose of
> the BB mark in the first place. The manufacturer guarantees that blocks
> which are initially bad will have at least one zero bit in the position
> of the BB mark. That's all to it.

Yes, it is a misinterpretation, and it's really irrelevant in many cases
whether or not the BB mark is written to each block's OOB. But it does
still provide some resilience in case the on-flash table ever gets
completely corrupted -- nand_bbt will rescan the flash for BB marks on
the next boot (and this will be totally broken--with or without
NO_OOB_BBM--for hardware like yours). Or to put it another way, it
supports some legacy scenarios without (AFAICT) any real negative
effects.

> There is no guarantee, that you will even be able to write any
> deterministic data to a block that has turned bad due to wearout or
> other flash defects.

Certainly. But that's not an argument against attempting.

> It is rather bogus to rely on data written to a
> known bad block to reflect the state of the block.

We don't "rely" on this. If the BBT (and its mirrors) never completely
fails, these marks are never used.

> > Also, as I noted in [1], I don't really like exposing a ton of
> > individual boolean DT properties like this. (At least this property is
> > orthogonal to the bad block table; I was a little off-base in [1].)
> > 
> How else should this information be conveyed to the flash drivers?

I'm not convinced the NO_OOB_BBM DT property is actually necessary at
all.

I was more concerned about bad block *table* properties, where I see
that at least some users (e.g. ST Micro's BCH NAND driver) expect a
different BBT format than the default, and we might begin to see extra
boolean flags for random bits of differentiation. This is apparently
still just a theoretical concern, though.

Brian

^ permalink raw reply

* linux-next: build failure after merge of the usb tree
From: Greg KH @ 2014-07-24  7:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140724170755.035cea1c@canb.auug.org.au>

On Thu, Jul 24, 2014 at 05:07:55PM +1000, Stephen Rothwell wrote:
> Hi Greg,
> 
> After merging the usb tree, today's linux-next build (x86_64 allmodconfig)
> failed like this:
> 
> drivers/phy/phy-spear1310-miphy.c: In function 'spear1310_miphy_probe':
> drivers/phy/phy-spear1310-miphy.c:232:14: warning: passing argument 2 of 'devm_phy_create' from incompatible pointer type
>   priv->phy = devm_phy_create(dev, &spear1310_miphy_ops, NULL);
>               ^
> In file included from drivers/phy/phy-spear1310-miphy.c:21:0:
> include/linux/phy/phy.h:164:13: note: expected 'struct device_node *' but argument is of type 'struct phy_ops *'
>  struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>              ^
> drivers/phy/phy-spear1310-miphy.c:232:14: error: too few arguments to function 'devm_phy_create'
>   priv->phy = devm_phy_create(dev, &spear1310_miphy_ops, NULL);
>               ^
> In file included from drivers/phy/phy-spear1310-miphy.c:21:0:
> include/linux/phy/phy.h:164:13: note: declared here
>  struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>              ^
> drivers/phy/phy-spear1340-miphy.c: In function 'spear1340_miphy_probe':
> drivers/phy/phy-spear1340-miphy.c:264:14: warning: passing argument 2 of 'devm_phy_create' from incompatible pointer type
>   priv->phy = devm_phy_create(dev, &spear1340_miphy_ops, NULL);
>               ^
> In file included from drivers/phy/phy-spear1340-miphy.c:21:0:
> include/linux/phy/phy.h:164:13: note: expected 'struct device_node *' but argument is of type 'struct phy_ops *'
>  struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>              ^
> drivers/phy/phy-spear1340-miphy.c:264:14: error: too few arguments to function 'devm_phy_create'
>   priv->phy = devm_phy_create(dev, &spear1340_miphy_ops, NULL);
>               ^
> In file included from drivers/phy/phy-spear1340-miphy.c:21:0:
> include/linux/phy/phy.h:164:13: note: declared here
>  struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>              ^
> 
> Caused by commit f0ed817638b5 ("phy: core: Let node ptr of PHY point to
> PHY and not of PHY provider") interacting with commit 64562e99477f
> ("phy: Add drivers for PCIe and SATA phy on SPEAr13xx") from the
> arm-soc tree.
> 
> I fixed that up and then got:
> 
> drivers/pinctrl/pinctrl-tegra-xusb.c: In function 'tegra_xusb_padctl_probe':
> drivers/pinctrl/pinctrl-tegra-xusb.c:913:8: warning: passing argument 2 of 'devm_phy_create' from incompatible pointer type
>   phy = devm_phy_create(&pdev->dev, &pcie_phy_ops, NULL);
>         ^
> In file included from drivers/pinctrl/pinctrl-tegra-xusb.c:18:0:
> include/linux/phy/phy.h:164:13: note: expected 'struct device_node *' but argument is of type 'const struct phy_ops *'
>  struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>              ^
> drivers/pinctrl/pinctrl-tegra-xusb.c:913:8: error: too few arguments to function 'devm_phy_create'
>   phy = devm_phy_create(&pdev->dev, &pcie_phy_ops, NULL);
>         ^
> In file included from drivers/pinctrl/pinctrl-tegra-xusb.c:18:0:
> include/linux/phy/phy.h:164:13: note: declared here
>  struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>              ^
> drivers/pinctrl/pinctrl-tegra-xusb.c:922:8: warning: passing argument 2 of 'devm_phy_create' from incompatible pointer type
>   phy = devm_phy_create(&pdev->dev, &sata_phy_ops, NULL);
>         ^
> In file included from drivers/pinctrl/pinctrl-tegra-xusb.c:18:0:
> include/linux/phy/phy.h:164:13: note: expected 'struct device_node *' but argument is of type 'const struct phy_ops *'
>  struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>              ^
> drivers/pinctrl/pinctrl-tegra-xusb.c:922:8: error: too few arguments to function 'devm_phy_create'
>   phy = devm_phy_create(&pdev->dev, &sata_phy_ops, NULL);
>         ^
> In file included from drivers/pinctrl/pinctrl-tegra-xusb.c:18:0:
> include/linux/phy/phy.h:164:13: note: declared here
>  struct phy *devm_phy_create(struct device *dev, struct device_node *node,
>              ^
> 
> From an interaction with commit dc0a39386687 ("pinctrl: Add NVIDIA
> Tegra XUSB pad controller support") from the arm-soc tree.
> 
> Final merge fix patch:

Ugh, what a mess, sorry about that.  I'll keep this around for if I end
up merging with Linus after these other trees get merged.

thanks for doing this,

greg k-h

^ permalink raw reply

* Issue found in Armada 370: "No buffer space available" error during continuous ping
From: Maggie Mae Roxas @ 2014-07-24  7:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140723061659.GE30488@1wt.eu>

Hi Willy,
Good day.

> I have no idea, I remember that this code is deeply burried into the
> original neta code. There was also a large code for the network
> classifier and something like buffer management in the original
> Marvell's driver if my memory serves me correctly, I have no idea
> if these ones set up anything special.
I also have no idea on this.

> Just the original ones. I have a mirabox with its original boot loader :
> U-Boot 2009.08 (Sep 16 2012 - 22:50:06)Marvell version: 1.1.2 NQ
This, I think, is a 2012_Q4 (QA) release if it's based on 2009.08.
We use a 2014_T1 (QA) release based on 2011.12.
# So we're using different boot loaders.

> I think we could try to dump all of our respective mvneta registers and
> compare them, though I have very little time for this today. And if it
> comes from extra SoC functions like buffer management or network classifier,
> I have no idea how they work nor what to dump :-/
Yes, I think the difference in bootloaders especially on mvneta
registers' values matter on our difference in behavior.

And indeed, it would take much of our time if we need to compare all
mvneta register dumps, and we'd need to forward those values directly
to a Marvell contact for more effective evaluation since it's more of
a hardware stuff. :-/

In any case, since performance and Tx interrupts were both still OK on
us, I think it's enough.
We'll just inform you if we notice some irregularities.

Thank you very much for discussing this issue with us! :-)

Until our future discussions,
Maggie Roxas

On Tue, Jul 22, 2014 at 11:16 PM, Willy Tarreau <w@1wt.eu> wrote:
> Hi Maggie,
>
> On Tue, Jul 22, 2014 at 07:24:35PM -0700, Maggie Mae Roxas wrote:
>> Hi Willy,
>> Good day.
>>
>> > OK so clearly the issue must be found.
>>
>> Actually we have 2 products using Armada 370.
>> One has only 1 ethernet port, so it is expected to act as Client only.
>> The other one has 2 ethernet ports, so it's more router-like.
>>
>> For the product with one port, we have checked the combination patch
>> and it seems like Tx IRQ is increasing so it's OK. We checked this via
>> /proc/interrupts and mvneta's value there changed from 500000+ to
>> around 900000+ after we perform a 10-iteration iperf to the server.
>> The throughput is also OK, we're getting around 850Mbits when we use a
>> 1Gbit connection, which is roughly just the same as what we've been
>> experiencing when we're still using 3.10.x (even 3.2.x).
>
> OK.
>
>> As for the other product with two ports, we do expect that we might be
>> encountering the slow performance you mentioned.
>> But we are not focusing on this project yet so once it's active again,
>> I'll let you know.
>>
>> > Just thinking about something, do you have a custom boot loader ?
>> > It would be possible that in our case, the Tx IRQ works only because some
>> > obscure or undocumented bits are set by the boot loader and that in your
>> > case it's not pre-initialized.
>>
>> We are indeed using a "custom" boot loader.
>> We are using Marvell u-boot 2014_T1.1 (latest QA release, I think).
>> We applied some patches to memory (since we have 1Gb DDR), some bits
>> and pieces for the interfaces we're going to support and not to
>> support, and of course our own environment variables.
>> As for the DDR memory/register patches, they came directly from our
>> Marvell contact.
>>
>> But with what I mentioned above, I think our Tx interrupt is working...?
>
> Yes, seems so.
>
>> BTW, for both products we've designed from Armada 370 RD, we didn't
>> use a switch. So we removed all switch-related codes in the boot
>> loader.
>> I'm not sure if not having switch affects the behavior?
>
> I have no idea, I remember that this code is deeply burried into the
> original neta code. There was also a large code for the network
> classifier and something like buffer management in the original
> Marvell's driver if my memory serves me correctly, I have no idea
> if these ones set up anything special.
>
>> How about you? May I know what boot loader you are using?
>
> Just the original ones. I have a mirabox with its original boot loader :
>
>     U-Boot 2009.08 (Sep 16 2012 - 22:50:06)Marvell version: 1.1.2 NQ
>     U-Boot Addressing:
>            Code:            00600000:006AFFF0
>            BSS:             006F8E40
>            Stack:           0x5fff70
>            PageTable:       0x8e0000
>            Heap address:    0x900000:0xe00000
>     Board: DB-88F6710-BP
>     SoC:   MV6710 A1
>     CPU:   Marvell PJ4B v7 UP (Rev 1) LE
>            CPU @ 1200Mhz, L2 @ 600Mhz
>            DDR @ 600Mhz, TClock @ 200Mhz
>            DDR 16Bit Width, FastPath Memory Access
>     PEX 0: Detected No Link.
>     PEX 1: Root Complex Interface, Detected Link X1
>     DRAM:   1 GB
>            CS 0: base 0x00000000 size 512 MB
>            CS 1: base 0x20000000 size 512 MB
>            Addresses 14M - 0M are saved for the U-Boot usage.
>     NAND:  1024 MiB
>     Bad block table found at page 262016, version 0x01
>     Bad block table found at page 261888, version 0x01
>     FPU not initialized
>     USB 0: Host Mode
>     USB 1: Host Mode
>     Modules/Interfaces Detected:
>            RGMII0 Phy
>            RGMII1 Phy
>            PEX0 (Lane 0)
>            PEX1 (Lane 1)
>     phy16= 72
>     phy16= 72
>     MMC:   MRVL_MMC: 0
>     Net:   egiga0 [PRIME], egiga1
>     Hit any key to stop autoboot:  0
>
>> > LTS would probably even interest your customer as it's an LTS version.
>> > In this case, always pick the most recent one (3.14.12 today). You may
>> > even be interested in 3.15.6 which contains another phy fix supposed to
>> > fix cd71e2, but if you're saying that it doesn't change anything for you
>> > I guess it will have no effet (might be worth testing for the purpose of
>> > helping troubleshooting though).
>>
>> Thank you for this advise, we'll take note of this.
>> We plan to stick on using LTS from now on, as much as possible.
>>
>> > OK. I still have a hard time imagining how hardware itself could prevent
>> > an IRQ from being delivered from a NIC which is located inside the SoC,
>> > but there must be an explanation somewhere :-/
>> I also would like to know how. :-/
>> But maybe it's our difference in boot loader as you speculated.
>
> I think we could try to dump all of our respective mvneta registers and
> compare them, though I have very little time for this today. And if it
> comes from extra SoC functions like buffer management or network classifier,
> I have no idea how they work nor what to dump :-/
>
> Regards,
> Willy
>

^ permalink raw reply

* linux-next: build failure after merge of the usb tree
From: Stephen Rothwell @ 2014-07-24  7:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Greg,

After merging the usb tree, today's linux-next build (x86_64 allmodconfig)
failed like this:

drivers/phy/phy-spear1310-miphy.c: In function 'spear1310_miphy_probe':
drivers/phy/phy-spear1310-miphy.c:232:14: warning: passing argument 2 of 'devm_phy_create' from incompatible pointer type
  priv->phy = devm_phy_create(dev, &spear1310_miphy_ops, NULL);
              ^
In file included from drivers/phy/phy-spear1310-miphy.c:21:0:
include/linux/phy/phy.h:164:13: note: expected 'struct device_node *' but argument is of type 'struct phy_ops *'
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
             ^
drivers/phy/phy-spear1310-miphy.c:232:14: error: too few arguments to function 'devm_phy_create'
  priv->phy = devm_phy_create(dev, &spear1310_miphy_ops, NULL);
              ^
In file included from drivers/phy/phy-spear1310-miphy.c:21:0:
include/linux/phy/phy.h:164:13: note: declared here
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
             ^
drivers/phy/phy-spear1340-miphy.c: In function 'spear1340_miphy_probe':
drivers/phy/phy-spear1340-miphy.c:264:14: warning: passing argument 2 of 'devm_phy_create' from incompatible pointer type
  priv->phy = devm_phy_create(dev, &spear1340_miphy_ops, NULL);
              ^
In file included from drivers/phy/phy-spear1340-miphy.c:21:0:
include/linux/phy/phy.h:164:13: note: expected 'struct device_node *' but argument is of type 'struct phy_ops *'
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
             ^
drivers/phy/phy-spear1340-miphy.c:264:14: error: too few arguments to function 'devm_phy_create'
  priv->phy = devm_phy_create(dev, &spear1340_miphy_ops, NULL);
              ^
In file included from drivers/phy/phy-spear1340-miphy.c:21:0:
include/linux/phy/phy.h:164:13: note: declared here
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
             ^

Caused by commit f0ed817638b5 ("phy: core: Let node ptr of PHY point to
PHY and not of PHY provider") interacting with commit 64562e99477f
("phy: Add drivers for PCIe and SATA phy on SPEAr13xx") from the
arm-soc tree.

I fixed that up and then got:

drivers/pinctrl/pinctrl-tegra-xusb.c: In function 'tegra_xusb_padctl_probe':
drivers/pinctrl/pinctrl-tegra-xusb.c:913:8: warning: passing argument 2 of 'devm_phy_create' from incompatible pointer type
  phy = devm_phy_create(&pdev->dev, &pcie_phy_ops, NULL);
        ^
In file included from drivers/pinctrl/pinctrl-tegra-xusb.c:18:0:
include/linux/phy/phy.h:164:13: note: expected 'struct device_node *' but argument is of type 'const struct phy_ops *'
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
             ^
drivers/pinctrl/pinctrl-tegra-xusb.c:913:8: error: too few arguments to function 'devm_phy_create'
  phy = devm_phy_create(&pdev->dev, &pcie_phy_ops, NULL);
        ^
In file included from drivers/pinctrl/pinctrl-tegra-xusb.c:18:0:
include/linux/phy/phy.h:164:13: note: declared here
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
             ^
drivers/pinctrl/pinctrl-tegra-xusb.c:922:8: warning: passing argument 2 of 'devm_phy_create' from incompatible pointer type
  phy = devm_phy_create(&pdev->dev, &sata_phy_ops, NULL);
        ^
In file included from drivers/pinctrl/pinctrl-tegra-xusb.c:18:0:
include/linux/phy/phy.h:164:13: note: expected 'struct device_node *' but argument is of type 'const struct phy_ops *'
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
             ^
drivers/pinctrl/pinctrl-tegra-xusb.c:922:8: error: too few arguments to function 'devm_phy_create'
  phy = devm_phy_create(&pdev->dev, &sata_phy_ops, NULL);
        ^
In file included from drivers/pinctrl/pinctrl-tegra-xusb.c:18:0:
include/linux/phy/phy.h:164:13: note: declared here
 struct phy *devm_phy_create(struct device *dev, struct device_node *node,
             ^

>From an interaction with commit dc0a39386687 ("pinctrl: Add NVIDIA
Tegra XUSB pad controller support") from the arm-soc tree.

Final merge fix patch:

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Thu, 24 Jul 2014 16:55:16 +1000
Subject: [PATCH] phy: fix up for devm_phy_create api change

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 drivers/phy/phy-spear1310-miphy.c    | 2 +-
 drivers/phy/phy-spear1340-miphy.c    | 2 +-
 drivers/pinctrl/pinctrl-tegra-xusb.c | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c
index c58c869d57e0..6dcbfcddb372 100644
--- a/drivers/phy/phy-spear1310-miphy.c
+++ b/drivers/phy/phy-spear1310-miphy.c
@@ -229,7 +229,7 @@ static int spear1310_miphy_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	priv->phy = devm_phy_create(dev, &spear1310_miphy_ops, NULL);
+	priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops, NULL);
 	if (IS_ERR(priv->phy)) {
 		dev_err(dev, "failed to create SATA PCIe PHY\n");
 		return PTR_ERR(priv->phy);
diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c
index 8de98adf21c3..7135ba2603b6 100644
--- a/drivers/phy/phy-spear1340-miphy.c
+++ b/drivers/phy/phy-spear1340-miphy.c
@@ -261,7 +261,7 @@ static int spear1340_miphy_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->misc);
 	}
 
-	priv->phy = devm_phy_create(dev, &spear1340_miphy_ops, NULL);
+	priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops, NULL);
 	if (IS_ERR(priv->phy)) {
 		dev_err(dev, "failed to create SATA PCIe PHY\n");
 		return PTR_ERR(priv->phy);
diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c
index 4a7daf577b49..a06620474845 100644
--- a/drivers/pinctrl/pinctrl-tegra-xusb.c
+++ b/drivers/pinctrl/pinctrl-tegra-xusb.c
@@ -910,7 +910,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
 		goto reset;
 	}
 
-	phy = devm_phy_create(&pdev->dev, &pcie_phy_ops, NULL);
+	phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops, NULL);
 	if (IS_ERR(phy)) {
 		err = PTR_ERR(phy);
 		goto unregister;
@@ -919,7 +919,7 @@ static int tegra_xusb_padctl_probe(struct platform_device *pdev)
 	padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy;
 	phy_set_drvdata(phy, padctl);
 
-	phy = devm_phy_create(&pdev->dev, &sata_phy_ops, NULL);
+	phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops, NULL);
 	if (IS_ERR(phy)) {
 		err = PTR_ERR(phy);
 		goto unregister;
-- 
2.0.1

-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au
-------------- 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/20140724/8c977cb0/attachment.sig>

^ permalink raw reply related


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