* [PATCH v9 2/4] ehci-platform: Add support for clks and phy passed through devicetree
From: Hans de Goede @ 2014-02-07 15:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391787403-20961-1-git-send-email-hdegoede@redhat.com>
Currently ehci-platform is only used in combination with devicetree when used
with some Via socs. By extending it to (optionally) get clks and a phy from
devicetree, and enabling / disabling those on power_on / off, it can be used
more generically. Specifically after this commit it can be used for the
ehci controller on Allwinner sunxi SoCs.
Since ehci-platform is intended to handle any generic enough non pci ehci
device, add a "usb-ehci" compatibility string.
There already is a usb-ehci device-tree bindings document, update this
with clks and phy bindings info.
Although actually quite generic so far the via,vt8500 compatibilty string
had its own bindings document. Somehow we even ended up with 2 of them. Since
these provide no extra information over the generic usb-ehci documentation,
this patch removes them.
The ehci-ppc-of.c driver also claims the usb-ehci compatibility string,
even though it mostly is ibm,usb-ehci-440epx specific. ehci-platform.c is
not needed on ppc platforms, so add a !PPC_OF dependency to it to avoid
2 drivers claiming the same compatibility string getting build on ppc.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
---
Documentation/devicetree/bindings/usb/usb-ehci.txt | 25 +++-
.../devicetree/bindings/usb/via,vt8500-ehci.txt | 15 ---
.../devicetree/bindings/usb/vt8500-ehci.txt | 12 --
drivers/usb/host/Kconfig | 1 +
drivers/usb/host/ehci-platform.c | 147 +++++++++++++++++----
5 files changed, 142 insertions(+), 58 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
delete mode 100644 Documentation/devicetree/bindings/usb/vt8500-ehci.txt
diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt
index fa18612..2c1aeeb 100644
--- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
+++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
@@ -7,13 +7,14 @@ Required properties:
(debug-port or other) can be also specified here, but only after
definition of standard EHCI registers.
- interrupts : one EHCI interrupt should be described here.
-If device registers are implemented in big endian mode, the device
-node should have "big-endian-regs" property.
-If controller implementation operates with big endian descriptors,
-"big-endian-desc" property should be specified.
-If both big endian registers and descriptors are used by the controller
-implementation, "big-endian" property can be specified instead of having
-both "big-endian-regs" and "big-endian-desc".
+
+Optional properties:
+ - big-endian-regs : boolean, set this for hcds with big-endian registers
+ - big-endian-desc : boolean, set this for hcds with big-endian descriptors
+ - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc
+ - clocks : a list of phandle + clock specifier pairs
+ - phys : phandle + phy specifier pair
+ - phy-names : "usb"
Example (Sequoia 440EPx):
ehci at e0000300 {
@@ -23,3 +24,13 @@ Example (Sequoia 440EPx):
reg = <0 e0000300 90 0 e0000390 70>;
big-endian;
};
+
+Example (Allwinner sun4i A10 SoC):
+ ehci0: usb at 01c14000 {
+ compatible = "allwinner,sun4i-a10-ehci", "usb-ehci";
+ reg = <0x01c14000 0x100>;
+ interrupts = <39>;
+ clocks = <&ahb_gates 1>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ };
diff --git a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
deleted file mode 100644
index 17b3ad1..0000000
--- a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-VIA/Wondermedia VT8500 EHCI Controller
------------------------------------------------------
-
-Required properties:
-- compatible : "via,vt8500-ehci"
-- reg : Should contain 1 register ranges(address and length)
-- interrupts : ehci controller interrupt
-
-Example:
-
- ehci at d8007900 {
- compatible = "via,vt8500-ehci";
- reg = <0xd8007900 0x200>;
- interrupts = <43>;
- };
diff --git a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
deleted file mode 100644
index 5fb8fd6..0000000
--- a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-VIA VT8500 and Wondermedia WM8xxx SoC USB controllers.
-
-Required properties:
- - compatible: Should be "via,vt8500-ehci" or "wm,prizm-ehci".
- - reg: Address range of the ehci registers. size should be 0x200
- - interrupts: Should contain the ehci interrupt.
-
-usb: ehci at D8007100 {
- compatible = "wm,prizm-ehci", "usb-ehci";
- reg = <0xD8007100 0x200>;
- interrupts = <1>;
-};
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a9707da..e28cbe0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -255,6 +255,7 @@ config USB_EHCI_ATH79
config USB_EHCI_HCD_PLATFORM
tristate "Generic EHCI driver for a platform device"
+ depends on !PPC_OF
default n
---help---
Adds an EHCI host driver for a generic platform device, which
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 01536cf..5ebd0b7 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -3,6 +3,7 @@
*
* Copyright 2007 Steven Brown <sbrown@cortland.com>
* Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
*
* Derived from the ohci-ssb driver
* Copyright 2007 Michael Buesch <m@bues.ch>
@@ -18,6 +19,7 @@
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
+#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/kernel.h>
@@ -25,6 +27,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
@@ -33,6 +36,13 @@
#include "ehci.h"
#define DRIVER_DESC "EHCI generic platform driver"
+#define EHCI_MAX_CLKS 3
+#define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv)
+
+struct ehci_platform_priv {
+ struct clk *clks[EHCI_MAX_CLKS];
+ struct phy *phy;
+};
static const char hcd_name[] = "ehci-platform";
@@ -64,38 +74,90 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
return 0;
}
+static int ehci_platform_power_on(struct platform_device *dev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
+ int clk, ret;
+
+ for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) {
+ ret = clk_prepare_enable(priv->clks[clk]);
+ if (ret)
+ goto err_disable_clks;
+ }
+
+ if (priv->phy) {
+ ret = phy_init(priv->phy);
+ if (ret)
+ goto err_disable_clks;
+
+ ret = phy_power_on(priv->phy);
+ if (ret)
+ goto err_exit_phy;
+ }
+
+ return 0;
+
+err_exit_phy:
+ phy_exit(priv->phy);
+err_disable_clks:
+ while (--clk >= 0)
+ clk_disable_unprepare(priv->clks[clk]);
+
+ return ret;
+}
+
+static void ehci_platform_power_off(struct platform_device *dev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
+ int clk;
+
+ if (priv->phy) {
+ phy_power_off(priv->phy);
+ phy_exit(priv->phy);
+ }
+
+ for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--)
+ if (priv->clks[clk])
+ clk_disable_unprepare(priv->clks[clk]);
+}
+
static struct hc_driver __read_mostly ehci_platform_hc_driver;
static const struct ehci_driver_overrides platform_overrides __initconst = {
- .reset = ehci_platform_reset,
+ .reset = ehci_platform_reset,
+ .extra_priv_size = sizeof(struct ehci_platform_priv),
};
-static struct usb_ehci_pdata ehci_platform_defaults;
+static struct usb_ehci_pdata ehci_platform_defaults = {
+ .power_on = ehci_platform_power_on,
+ .power_suspend = ehci_platform_power_off,
+ .power_off = ehci_platform_power_off,
+};
static int ehci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct resource *res_mem;
- struct usb_ehci_pdata *pdata;
- int irq;
- int err;
+ struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
+ struct ehci_platform_priv *priv;
+ int err, irq, clk = 0;
if (usb_disabled())
return -ENODEV;
/*
- * use reasonable defaults so platforms don't have to provide these.
- * with DT probing on ARM, none of these are set.
+ * Use reasonable defaults so platforms don't have to provide these
+ * with DT probing on ARM.
*/
- if (!dev_get_platdata(&dev->dev))
- dev->dev.platform_data = &ehci_platform_defaults;
+ if (!pdata)
+ pdata = &ehci_platform_defaults;
err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
if (err)
return err;
- pdata = dev_get_platdata(&dev->dev);
-
irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "no irq provided");
@@ -107,17 +169,40 @@ static int ehci_platform_probe(struct platform_device *dev)
return -ENXIO;
}
+ hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
+ dev_name(&dev->dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ platform_set_drvdata(dev, hcd);
+ dev->dev.platform_data = pdata;
+ priv = hcd_to_ehci_priv(hcd);
+
+ if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
+ priv->phy = devm_phy_get(&dev->dev, "usb");
+ if (IS_ERR(priv->phy)) {
+ err = PTR_ERR(priv->phy);
+ if (err == -EPROBE_DEFER)
+ goto err_put_hcd;
+ priv->phy = NULL;
+ }
+
+ for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
+ priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
+ if (IS_ERR(priv->clks[clk])) {
+ err = PTR_ERR(priv->clks[clk]);
+ if (err == -EPROBE_DEFER)
+ goto err_put_clks;
+ priv->clks[clk] = NULL;
+ break;
+ }
+ }
+ }
+
if (pdata->power_on) {
err = pdata->power_on(dev);
if (err < 0)
- return err;
- }
-
- hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
- dev_name(&dev->dev));
- if (!hcd) {
- err = -ENOMEM;
- goto err_power;
+ goto err_put_clks;
}
hcd->rsrc_start = res_mem->start;
@@ -126,22 +211,28 @@ static int ehci_platform_probe(struct platform_device *dev)
hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
if (IS_ERR(hcd->regs)) {
err = PTR_ERR(hcd->regs);
- goto err_put_hcd;
+ goto err_power;
}
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err)
- goto err_put_hcd;
+ goto err_power;
device_wakeup_enable(hcd->self.controller);
platform_set_drvdata(dev, hcd);
return err;
-err_put_hcd:
- usb_put_hcd(hcd);
err_power:
if (pdata->power_off)
pdata->power_off(dev);
+err_put_clks:
+ while (--clk >= 0)
+ clk_put(priv->clks[clk]);
+err_put_hcd:
+ if (pdata == &ehci_platform_defaults)
+ dev->dev.platform_data = NULL;
+
+ usb_put_hcd(hcd);
return err;
}
@@ -150,13 +241,19 @@ static int ehci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
+ struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
+ int clk;
usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
if (pdata->power_off)
pdata->power_off(dev);
+ for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++)
+ clk_put(priv->clks[clk]);
+
+ usb_put_hcd(hcd);
+
if (pdata == &ehci_platform_defaults)
dev->dev.platform_data = NULL;
@@ -207,8 +304,10 @@ static int ehci_platform_resume(struct device *dev)
static const struct of_device_id vt8500_ehci_ids[] = {
{ .compatible = "via,vt8500-ehci", },
{ .compatible = "wm,prizm-ehci", },
+ { .compatible = "usb-ehci", },
{}
};
+MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
static const struct platform_device_id ehci_platform_table[] = {
{ "ehci-platform", 0 },
--
1.8.4.2
^ permalink raw reply related
* [PATCH v9 1/4] ohci-platform: Add support for devicetree instantiation
From: Hans de Goede @ 2014-02-07 15:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391787403-20961-1-git-send-email-hdegoede@redhat.com>
Add support for ohci-platform instantiation from devicetree, including
optionally getting clks and a phy from devicetree, and enabling / disabling
those on power_on / off.
This should allow using ohci-platform from devicetree in various cases.
Specifically after this commit it can be used for the ohci controller found
on Allwinner sunxi SoCs.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
---
Documentation/devicetree/bindings/usb/usb-ohci.txt | 22 +++
drivers/usb/host/ohci-platform.c | 162 ++++++++++++++++++---
2 files changed, 162 insertions(+), 22 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/usb-ohci.txt
diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt
new file mode 100644
index 0000000..6ba38d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt
@@ -0,0 +1,22 @@
+USB OHCI controllers
+
+Required properties:
+- compatible : "usb-ohci"
+- reg : ohci controller register range (address and length)
+- interrupts : ohci controller interrupt
+
+Optional properties:
+- clocks : a list of phandle + clock specifier pairs
+- phys : phandle + phy specifier pair
+- phy-names : "usb"
+
+Example:
+
+ ohci0: usb at 01c14400 {
+ compatible = "allwinner,sun4i-a10-ohci", "usb-ohci";
+ reg = <0x01c14400 0x100>;
+ interrupts = <64>;
+ clocks = <&usb_clk 6>, <&ahb_gates 2>;
+ phys = <&usbphy 1>;
+ phy-names = "usb";
+ };
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index 68f674c..49304dd 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -3,6 +3,7 @@
*
* Copyright 2007 Michael Buesch <m@bues.ch>
* Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
*
* Derived from the OCHI-SSB driver
* Derived from the OHCI-PCI driver
@@ -14,11 +15,14 @@
* Licensed under the GNU/GPL. See COPYING for details.
*/
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
#include <linux/hrtimer.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/usb/ohci_pdriver.h>
#include <linux/usb.h>
@@ -27,6 +31,13 @@
#include "ohci.h"
#define DRIVER_DESC "OHCI generic platform driver"
+#define OHCI_MAX_CLKS 3
+#define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv)
+
+struct ohci_platform_priv {
+ struct clk *clks[OHCI_MAX_CLKS];
+ struct phy *phy;
+};
static const char hcd_name[] = "ohci-platform";
@@ -48,11 +59,67 @@ static int ohci_platform_reset(struct usb_hcd *hcd)
return ohci_setup(hcd);
}
+static int ohci_platform_power_on(struct platform_device *dev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
+ int clk, ret;
+
+ for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) {
+ ret = clk_prepare_enable(priv->clks[clk]);
+ if (ret)
+ goto err_disable_clks;
+ }
+
+ if (priv->phy) {
+ ret = phy_init(priv->phy);
+ if (ret)
+ goto err_disable_clks;
+
+ ret = phy_power_on(priv->phy);
+ if (ret)
+ goto err_exit_phy;
+ }
+
+ return 0;
+
+err_exit_phy:
+ phy_exit(priv->phy);
+err_disable_clks:
+ while (--clk >= 0)
+ clk_disable_unprepare(priv->clks[clk]);
+
+ return ret;
+}
+
+static void ohci_platform_power_off(struct platform_device *dev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
+ int clk;
+
+ if (priv->phy) {
+ phy_power_off(priv->phy);
+ phy_exit(priv->phy);
+ }
+
+ for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--)
+ if (priv->clks[clk])
+ clk_disable_unprepare(priv->clks[clk]);
+}
+
static struct hc_driver __read_mostly ohci_platform_hc_driver;
static const struct ohci_driver_overrides platform_overrides __initconst = {
- .product_desc = "Generic Platform OHCI controller",
- .reset = ohci_platform_reset,
+ .product_desc = "Generic Platform OHCI controller",
+ .reset = ohci_platform_reset,
+ .extra_priv_size = sizeof(struct ohci_platform_priv),
+};
+
+static struct usb_ohci_pdata ohci_platform_defaults = {
+ .power_on = ohci_platform_power_on,
+ .power_suspend = ohci_platform_power_off,
+ .power_off = ohci_platform_power_off,
};
static int ohci_platform_probe(struct platform_device *dev)
@@ -60,17 +127,23 @@ static int ohci_platform_probe(struct platform_device *dev)
struct usb_hcd *hcd;
struct resource *res_mem;
struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev);
- int irq;
- int err = -ENOMEM;
-
- if (!pdata) {
- WARN_ON(1);
- return -ENODEV;
- }
+ struct ohci_platform_priv *priv;
+ int err, irq, clk = 0;
if (usb_disabled())
return -ENODEV;
+ /*
+ * Use reasonable defaults so platforms don't have to provide these
+ * with DT probing on ARM.
+ */
+ if (!pdata)
+ pdata = &ohci_platform_defaults;
+
+ err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
+ if (err)
+ return err;
+
irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "no irq provided");
@@ -83,17 +156,40 @@ static int ohci_platform_probe(struct platform_device *dev)
return -ENXIO;
}
+ hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev,
+ dev_name(&dev->dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ platform_set_drvdata(dev, hcd);
+ dev->dev.platform_data = pdata;
+ priv = hcd_to_ohci_priv(hcd);
+
+ if (pdata == &ohci_platform_defaults && dev->dev.of_node) {
+ priv->phy = devm_phy_get(&dev->dev, "usb");
+ if (IS_ERR(priv->phy)) {
+ err = PTR_ERR(priv->phy);
+ if (err == -EPROBE_DEFER)
+ goto err_put_hcd;
+ priv->phy = NULL;
+ }
+
+ for (clk = 0; clk < OHCI_MAX_CLKS; clk++) {
+ priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
+ if (IS_ERR(priv->clks[clk])) {
+ err = PTR_ERR(priv->clks[clk]);
+ if (err == -EPROBE_DEFER)
+ goto err_put_clks;
+ priv->clks[clk] = NULL;
+ break;
+ }
+ }
+ }
+
if (pdata->power_on) {
err = pdata->power_on(dev);
if (err < 0)
- return err;
- }
-
- hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev,
- dev_name(&dev->dev));
- if (!hcd) {
- err = -ENOMEM;
- goto err_power;
+ goto err_put_clks;
}
hcd->rsrc_start = res_mem->start;
@@ -102,11 +198,11 @@ static int ohci_platform_probe(struct platform_device *dev)
hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
if (IS_ERR(hcd->regs)) {
err = PTR_ERR(hcd->regs);
- goto err_put_hcd;
+ goto err_power;
}
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err)
- goto err_put_hcd;
+ goto err_power;
device_wakeup_enable(hcd->self.controller);
@@ -114,11 +210,17 @@ static int ohci_platform_probe(struct platform_device *dev)
return err;
-err_put_hcd:
- usb_put_hcd(hcd);
err_power:
if (pdata->power_off)
pdata->power_off(dev);
+err_put_clks:
+ while (--clk >= 0)
+ clk_put(priv->clks[clk]);
+err_put_hcd:
+ if (pdata == &ohci_platform_defaults)
+ dev->dev.platform_data = NULL;
+
+ usb_put_hcd(hcd);
return err;
}
@@ -127,13 +229,22 @@ static int ohci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev);
+ struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
+ int clk;
usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
if (pdata->power_off)
pdata->power_off(dev);
+ for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++)
+ clk_put(priv->clks[clk]);
+
+ usb_put_hcd(hcd);
+
+ if (pdata == &ohci_platform_defaults)
+ dev->dev.platform_data = NULL;
+
return 0;
}
@@ -180,6 +291,12 @@ static int ohci_platform_resume(struct device *dev)
#define ohci_platform_resume NULL
#endif /* CONFIG_PM */
+static const struct of_device_id ohci_platform_ids[] = {
+ { .compatible = "usb-ohci", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ohci_platform_ids);
+
static const struct platform_device_id ohci_platform_table[] = {
{ "ohci-platform", 0 },
{ }
@@ -200,6 +317,7 @@ static struct platform_driver ohci_platform_driver = {
.owner = THIS_MODULE,
.name = "ohci-platform",
.pm = &ohci_platform_pm_ops,
+ .of_match_table = ohci_platform_ids,
}
};
--
1.8.4.2
^ permalink raw reply related
* [PATCH v9 0/4] ohci-platform and ehci-plaform patches rebased on 3.14-rc1
From: Hans de Goede @ 2014-02-07 15:36 UTC (permalink / raw)
To: linux-arm-kernel
Hi Greg,
Here is v9 of my ohci-platform and ehci-platform patchset, It is just a
rebase (with some manual conflict resolution), to make it easier for you
to throw this into usb-next, there are no other changes.
Thanks & Regards,
Hans
^ permalink raw reply
* [PATCH v2 1/2] PM / OPP: Allow boost frequency to be looked up from device tree
From: Nishanth Menon @ 2014-02-07 15:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786342-11812-2-git-send-email-thomas.ab@samsung.com>
On Fri, Feb 7, 2014 at 9:19 AM, Thomas Abraham <ta.omasab@gmail.com> wrote:
> From: Thomas Abraham <thomas.ab@samsung.com>
>
> Commit 6f19efc0 ("cpufreq: Add boost frequency support in core") adds
> support for CPU boost mode. This patch adds support for finding available
> boost frequencies from device tree and marking them as usable in boost mode.
>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
> drivers/base/power/opp.c | 34 +++++++++++++++++++++++++++++++++-
> 1 file changed, 33 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
> index fa41874..b636826 100644
> --- a/drivers/base/power/opp.c
> +++ b/drivers/base/power/opp.c
> @@ -628,7 +628,8 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
> struct device_opp *dev_opp;
> struct dev_pm_opp *opp;
> struct cpufreq_frequency_table *freq_table;
> - int i = 0;
> + int i = 0, j, len, ret;
> + u32 *boost_freqs = NULL;
>
> /* Pretend as if I am an updater */
> mutex_lock(&dev_opp_list_lock);
> @@ -650,10 +651,35 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
> return -ENOMEM;
> }
>
> + if (of_find_property(dev->of_node, "boost-frequency", &len)) {
> + if (len == 0 || (len & (sizeof(u32) - 1)) != 0) {
> + dev_err(dev, "%s: invalid boost frequency\n", __func__);
> + ret = -EINVAL;
> + goto err_boost;
> + }
> +
> + boost_freqs = kzalloc(len, GFP_KERNEL);
> + if (!boost_freqs) {
> + dev_warn(dev, "%s: no memory for boost freq table\n",
> + __func__);
> + ret = -ENOMEM;
> + goto err_boost;
> + }
> + of_property_read_u32_array(dev->of_node, "boost-frequency",
> + boost_freqs, len / sizeof(u32));
> + }
> +
> list_for_each_entry(opp, &dev_opp->opp_list, node) {
> if (opp->available) {
> freq_table[i].driver_data = i;
> freq_table[i].frequency = opp->rate / 1000;
> + for (j = 0; j < len / sizeof(u32) && boost_freqs; j++) {
> + if (boost_freqs[j] == freq_table[i].frequency) {
> + freq_table[i].driver_data =
> + CPUFREQ_BOOST_FREQ;
> + break;
> + }
> + }
What if any one of the boost_freqs are not contained in the enabled frequencies?
> i++;
> }
> }
> @@ -663,8 +689,14 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
> freq_table[i].frequency = CPUFREQ_TABLE_END;
>
> *table = &freq_table[0];
> + kfree(boost_freqs);
>
> return 0;
> +
> +err_boost:
> + kfree(freq_table);
> + mutex_unlock(&dev_opp_list_lock);
> + return ret;
> }
> EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table);
>
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" 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 v2 2/2] Documentation: devicetree: Add boost-frequency binding to list boost mode frequency
From: Nishanth Menon @ 2014-02-07 15:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786342-11812-3-git-send-email-thomas.ab@samsung.com>
On Fri, Feb 7, 2014 at 9:19 AM, Thomas Abraham <ta.omasab@gmail.com> wrote:
> From: Thomas Abraham <thomas.ab@samsung.com>
>
> Add a new optional boost-frequency binding for specifying the frequencies
> usable in boost mode.
>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: Lukasz Majewski <l.majewski@samsung.com>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: Kumar Gala <galak@codeaurora.org>
> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> ---
> Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt | 11 +++++++++++
> 1 file changed, 11 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt
>
> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt
> new file mode 100644
> index 0000000..d925e38
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt
> @@ -0,0 +1,11 @@
> +* Device tree binding for CPU boost frequency (aka over-clocking)
> +
> +Certain CPU's can be operated in optional 'boost' mode (or sometimes referred as
> +overclocking) in which the CPU can operate in frequencies beyond the normal
> +operating conditions.
> +
> +Optional Properties:
> +- boost-frequency: list of frequencies in KHz to be used only in boost mode.
boost-frequencies?
> + This list should be a subset of frequencies listed in "operating-points"
> + property. Refer to Documentation/devicetree/bindings/power/opp.txt for
> + details about "operating-points" property.
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" 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 v4 5/5] ARM: sun7i: dt: Add bindings for USB clocks
From: Hans de Goede @ 2014-02-07 15:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786513-20780-1-git-send-email-hdegoede@redhat.com>
From: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 316cab8..14d9696 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -289,6 +289,15 @@
clock-output-names = "ir1";
};
+ usb_clk: clk at 01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-a10-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+ };
+
spi3_clk: clk at 01c200d4 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
--
1.8.4.2
^ permalink raw reply related
* [PATCH v4 4/5] ARM: sun5i: dt: Add bindings for USB clocks
From: Hans de Goede @ 2014-02-07 15:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786513-20780-1-git-send-email-hdegoede@redhat.com>
From: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun5i-a10s.dtsi | 9 +++++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 9 +++++++++
2 files changed, 18 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 38d01bd..2ed7429 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -264,6 +264,15 @@
clock-output-names = "ir0";
};
+ usb_clk: clk at 01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun5i-a13-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_phy";
+ };
+
mbus_clk: clk at 01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index ddd39d3..30ece67 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -261,6 +261,15 @@
clock-output-names = "ir0";
};
+ usb_clk: clk at 01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun5i-a13-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_phy";
+ };
+
mbus_clk: clk at 01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
--
1.8.4.2
^ permalink raw reply related
* [PATCH v4 3/5] ARM: sun4i: dt: Add bindings for USB clocks
From: Hans de Goede @ 2014-02-07 15:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786513-20780-1-git-send-email-hdegoede@redhat.com>
From: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index ebb4cd0..8d10f27 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -301,6 +301,15 @@
clock-output-names = "ir1";
};
+ usb_clk: clk at 01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-a10-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+ };
+
spi3_clk: clk at 01c200d4 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
--
1.8.4.2
^ permalink raw reply related
* [PATCH v4 2/5] clk: sunxi: Add USB clock register defintions
From: Hans de Goede @ 2014-02-07 15:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786513-20780-1-git-send-email-hdegoede@redhat.com>
From: Roman Byshko <rbyshko@gmail.com>
Add register definitions for the usb-clk register found on sun4i, sun5i and
sun7i SoCs.
Signed-off-by: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 5 +++++
drivers/clk/sunxi/clk-sunxi.c | 12 ++++++++++++
2 files changed, 17 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 27f19f1..5aa8d6d 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -38,6 +38,8 @@ Required properties:
"allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
"allwinner,sun7i-a20-out-clk" - for the external output clocks
"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
+ "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
+ "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
Required properties for all clocks:
- reg : shall be the control register address for the clock.
@@ -54,6 +56,9 @@ Required properties for all clocks:
For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
dummy clocks at 25 MHz and 125 MHz, respectively. See example.
+And "allwinner,*-usb-clk" clocks also require:
+- reset-cells : shall be set to 1
+
Clock consumers should specify the desired clocks they use with a
"clocks" phandle cell. Consumers that are using a gated clock should
provide an additional ID in their clock property. This ID is the
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 1e15e4c..61e57d2 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -910,6 +910,16 @@ static const struct gates_data sun4i_ahb_gates_data __initconst = {
.mask = {0x7F77FFF, 0x14FB3F},
};
+static const struct gates_data sun4i_a10_usb_gates_data __initconst = {
+ .mask = {0x1C0},
+ .reset_mask = 0x07,
+};
+
+static const struct gates_data sun5i_a13_usb_gates_data __initconst = {
+ .mask = {0x140},
+ .reset_mask = 0x03,
+};
+
static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
.mask = {0x147667e7, 0x185915},
};
@@ -1257,6 +1267,8 @@ static const struct of_device_id clk_gates_match[] __initconst = {
{.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
{.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
{.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
+ {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,},
+ {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,},
{}
};
--
1.8.4.2
^ permalink raw reply related
* [PATCH v4 1/5] clk: sunxi: Add support for USB clock-register reset bits
From: Hans de Goede @ 2014-02-07 15:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786513-20780-1-git-send-email-hdegoede@redhat.com>
The usb-clk register is special in that it not only contains clk gate bits,
but also has a few reset bits. This commit adds support for this by allowing
gates type sunxi clks to also register a reset controller.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/clk/sunxi/clk-sunxi.c | 71 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 64bda21..1e15e4c 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -18,6 +18,7 @@
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/reset-controller.h>
#include "clk-factors.h"
@@ -838,6 +839,59 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
/**
+ * sunxi_gates_reset... - reset bits in leaf gate clk registers handling
+ */
+
+struct gates_reset_data {
+ void __iomem *reg;
+ spinlock_t *lock;
+ struct reset_controller_dev rcdev;
+};
+
+static int sunxi_gates_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct gates_reset_data *data = container_of(rcdev,
+ struct gates_reset_data,
+ rcdev);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(data->lock, flags);
+
+ reg = readl(data->reg);
+ writel(reg & ~BIT(id), data->reg);
+
+ spin_unlock_irqrestore(data->lock, flags);
+
+ return 0;
+}
+
+static int sunxi_gates_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct gates_reset_data *data = container_of(rcdev,
+ struct gates_reset_data,
+ rcdev);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(data->lock, flags);
+
+ reg = readl(data->reg);
+ writel(reg | BIT(id), data->reg);
+
+ spin_unlock_irqrestore(data->lock, flags);
+
+ return 0;
+}
+
+static struct reset_control_ops sunxi_gates_reset_ops = {
+ .assert = sunxi_gates_reset_assert,
+ .deassert = sunxi_gates_reset_deassert,
+};
+
+/**
* sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
*/
@@ -845,6 +899,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
struct gates_data {
DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
+ u32 reset_mask;
};
static const struct gates_data sun4i_axi_gates_data __initconst = {
@@ -915,6 +970,7 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
struct gates_data *data)
{
struct clk_onecell_data *clk_data;
+ struct gates_reset_data *reset_data;
const char *clk_parent;
const char *clk_name;
void *reg;
@@ -958,6 +1014,21 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
clk_data->clk_num = i;
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ /* Register a reset controler for gates with reset bits */
+ if (data->reset_mask == 0)
+ return;
+
+ reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
+ if (!reset_data)
+ return;
+
+ reset_data->reg = reg;
+ reset_data->lock = &clk_lock;
+ reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1;
+ reset_data->rcdev.ops = &sunxi_gates_reset_ops;
+ reset_data->rcdev.of_node = node;
+ reset_controller_register(&reset_data->rcdev);
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH v4 0/5] clk: sunxi usb clks support
From: Hans de Goede @ 2014-02-07 15:21 UTC (permalink / raw)
To: linux-arm-kernel
Hi All,
And here is v4 of my sunxi usb clks support series.
Changes since v2:
-rename the compatibilty strings from foo-usb-gates-clk to foo-usb-clk
Changes since v3:
-rename the compatibilty string for sun4i-usb-clk to sun4i-a10-usb-clk
Note the dts bits (patches 3-5) of this series depends on Chen-Yu Tsai's clk
rename series.
Emilio, should Mike pick patches 1-2 up directly, or should they go through
your tree?
Maxime, can you please add patches 3-5 to your dts tree ? Assuming that
wens clk rename patches are already there.
Thanks & Regards,
Hans
^ permalink raw reply
* Re: [PATCH 5/8] tty/serial: at91: add dtr control via gpio
From: Alexander Shiyan @ 2014-02-07 15:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-6-git-send-email-richard.genoud@gmail.com>
Hello.
???????, 7 ??????? 2014, 15:59 +01:00 ?? Richard Genoud <richard.genoud@gmail.com>:
> On sam9x5, the USART controller doesn't handle DTR/DSR/DCD/RI signals,
> so we have to control them via GPIO.
>
> This patch permits to use a GPIO to control the DTR signal.
>
> Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
> ---
...
> + if (gpio_is_valid(atmel_port->gpio.dtr)) {
> + if (mctrl & TIOCM_DTR)
> + gpio_set_value(atmel_port->gpio.dtr, 0);
> + else
> + gpio_set_value(atmel_port->gpio.dtr, 1);
> + }
So, if you use GPIO for such purpose (here and in the other patches),
you should take and use GPIO active level from bindings.
It will make use of GPIO more flexible and deliver us from further special
possible bindings to declare the active level.
Actually, it would be good to have a separate unit for mctrl GPIOs,
which could be used for other drivers.
---
^ permalink raw reply
* [PATCH v2 2/2] Documentation: devicetree: Add boost-frequency binding to list boost mode frequency
From: Thomas Abraham @ 2014-02-07 15:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786342-11812-1-git-send-email-thomas.ab@samsung.com>
From: Thomas Abraham <thomas.ab@samsung.com>
Add a new optional boost-frequency binding for specifying the frequencies
usable in boost mode.
Cc: Nishanth Menon <nm@ti.com>
Cc: Lukasz Majewski <l.majewski@samsung.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
---
Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt
diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt
new file mode 100644
index 0000000..d925e38
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt
@@ -0,0 +1,11 @@
+* Device tree binding for CPU boost frequency (aka over-clocking)
+
+Certain CPU's can be operated in optional 'boost' mode (or sometimes referred as
+overclocking) in which the CPU can operate in frequencies beyond the normal
+operating conditions.
+
+Optional Properties:
+- boost-frequency: list of frequencies in KHz to be used only in boost mode.
+ This list should be a subset of frequencies listed in "operating-points"
+ property. Refer to Documentation/devicetree/bindings/power/opp.txt for
+ details about "operating-points" property.
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 1/2] PM / OPP: Allow boost frequency to be looked up from device tree
From: Thomas Abraham @ 2014-02-07 15:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391786342-11812-1-git-send-email-thomas.ab@samsung.com>
From: Thomas Abraham <thomas.ab@samsung.com>
Commit 6f19efc0 ("cpufreq: Add boost frequency support in core") adds
support for CPU boost mode. This patch adds support for finding available
boost frequencies from device tree and marking them as usable in boost mode.
Cc: Nishanth Menon <nm@ti.com>
Cc: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
---
drivers/base/power/opp.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index fa41874..b636826 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -628,7 +628,8 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
struct device_opp *dev_opp;
struct dev_pm_opp *opp;
struct cpufreq_frequency_table *freq_table;
- int i = 0;
+ int i = 0, j, len, ret;
+ u32 *boost_freqs = NULL;
/* Pretend as if I am an updater */
mutex_lock(&dev_opp_list_lock);
@@ -650,10 +651,35 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
return -ENOMEM;
}
+ if (of_find_property(dev->of_node, "boost-frequency", &len)) {
+ if (len == 0 || (len & (sizeof(u32) - 1)) != 0) {
+ dev_err(dev, "%s: invalid boost frequency\n", __func__);
+ ret = -EINVAL;
+ goto err_boost;
+ }
+
+ boost_freqs = kzalloc(len, GFP_KERNEL);
+ if (!boost_freqs) {
+ dev_warn(dev, "%s: no memory for boost freq table\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err_boost;
+ }
+ of_property_read_u32_array(dev->of_node, "boost-frequency",
+ boost_freqs, len / sizeof(u32));
+ }
+
list_for_each_entry(opp, &dev_opp->opp_list, node) {
if (opp->available) {
freq_table[i].driver_data = i;
freq_table[i].frequency = opp->rate / 1000;
+ for (j = 0; j < len / sizeof(u32) && boost_freqs; j++) {
+ if (boost_freqs[j] == freq_table[i].frequency) {
+ freq_table[i].driver_data =
+ CPUFREQ_BOOST_FREQ;
+ break;
+ }
+ }
i++;
}
}
@@ -663,8 +689,14 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
freq_table[i].frequency = CPUFREQ_TABLE_END;
*table = &freq_table[0];
+ kfree(boost_freqs);
return 0;
+
+err_boost:
+ kfree(freq_table);
+ mutex_unlock(&dev_opp_list_lock);
+ return ret;
}
EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table);
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 0/2] Add device tree based lookup of boost mode frequency
From: Thomas Abraham @ 2014-02-07 15:19 UTC (permalink / raw)
To: linux-arm-kernel
Changes since v1:
- Boost mode frequencies are specfied as a set of frequencies instead of
specifying them as OPPs. Thanks to Nishanth, Lukasz and Rob for the
feedback.
Commit 6f19efc0 ("cpufreq: Add boost frequency support in core") adds
support for CPU boost mode for CPUfreq drivers. To use the new boost
mode, CPUfreq drivers have to specify the boost mode frequency and
voltage within the CPUfreq driver, which is the case for Exynos4x12
CPUfreq driver.
But for CPUfreq drivers which obtain the OPPs from cpus node, this
patch series adds support to specify boost mode frequencies in the
cpu device tree node. This requirement came up when Lukasz pointed
out the regression caused by the Exynos CPUfreq driver consolidation
patches.
Thomas Abraham (2):
PM / OPP: Allow boost frequency to be looked up from device tree
Documentation: devicetree: Add boost-frequency binding to list boost mode frequency
.../devicetree/bindings/cpufreq/cpufreq-boost.txt | 11 +++++++
drivers/base/power/opp.c | 34 +++++++++++++++++++-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt
^ permalink raw reply
* [PATCH] i2c: mv64xxx: Fix locked bus when offload is selected but not used on a message
From: Gregory CLEMENT @ 2014-02-07 15:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207150958.GY8533@titan.lakedaemon.net>
On 07/02/2014 16:09, Jason Cooper wrote:
> On Fri, Feb 07, 2014 at 11:55:54AM +0100, Gregory CLEMENT wrote:
>> Offload can be used only on regular transactions and for 1 to byte
>> transfers. In the other cases we switch back to usual work flow.
>>
>> In this case we need to call mv64xxx_i2c_prepare_for_io() as this
>> function is not used when we try to use offloading.
>>
>> This commit adds this missing call when offloading have failed in the
>> MV64XXX_I2C_ACTION_OFFLOAD_SEND_START case.
>>
>> This fix the timeout seen when the the i2c driver try to access an
>> address where the device is absent on the Armada XP bases board.
>>
>> Cc: stable at vger.kernel.org # v3.12+
>> Fixes: 930ab3d403ae (i2c: mv64xxx: Add I2C Transaction Generator support)
>>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>> drivers/i2c/busses/i2c-mv64xxx.c | 9 ++++++++-
>> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> I'd like to get a few tested-by's on this before this is pushed. We've
> had quite a bit of fixes this round :( Please test both multi_v7 and
> mvebu defconfigs.
Well of course I have tested with multi_v7 and mvebu defconfigs, but I
think it is not my tested-by that you want! :)
An for the test we only have to test the Armada XP B0 based board, because
in the other case the offload is disable, so the code I modified never
doesn't run.
Thanks,
Gregory
>
> Kevin, I know you're busy with a lot more than us, but if you could
> confirm that this fixes the bus hangs you reported, that would be great.
>
> thx,
>
> Jason.
>
>>
>> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
>> index b8c5187b9ee0..a1700c62d955 100644
>> --- a/drivers/i2c/busses/i2c-mv64xxx.c
>> +++ b/drivers/i2c/busses/i2c-mv64xxx.c
>> @@ -461,8 +461,15 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>> case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START:
>> if (!mv64xxx_i2c_offload_msg(drv_data))
>> break;
>> - else
>> + else {
>> drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
>> + /*
>> + * Switch to the standard path, so we finally need to
>> + * prepare the io that have not been done in
>> + * mv64xxx_i2c_execute_msg
>> + */
>> + mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
>> + }
>> /* FALLTHRU */
>> case MV64XXX_I2C_ACTION_SEND_START:
>> writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
>> --
>> 1.8.1.2
>>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH v6 05/19] watchdog: orion: Make sure the watchdog is initially stopped
From: Ezequiel Garcia @ 2014-02-07 15:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F4E1C1.4010805@roeck-us.net>
On Fri, Feb 07, 2014 at 05:38:09AM -0800, Guenter Roeck wrote:
> On 02/07/2014 02:40 AM, Ezequiel Garcia wrote:
> > On Thu, Feb 06, 2014 at 06:02:56PM -0800, Guenter Roeck wrote:
> >> On 02/06/2014 09:20 AM, Ezequiel Garcia wrote:
> >>> Having the watchdog initially fully stopped is important to avoid
> >>> any spurious watchdog triggers, in case the registers are not in
> >>> its reset state.
> >>>
> >>> Reviewed-by: Guenter Roeck <linux@roeck-us.net>
> >>> Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> >>> Tested-by: Willy Tarreau <w@1wt.eu>
> >>> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> >>> ---
> >>> drivers/watchdog/orion_wdt.c | 3 +++
> >>> 1 file changed, 3 insertions(+)
> >>>
> >>> diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
> >>> index 6746033..2dbeee9 100644
> >>> --- a/drivers/watchdog/orion_wdt.c
> >>> +++ b/drivers/watchdog/orion_wdt.c
> >>> @@ -142,6 +142,9 @@ static int orion_wdt_probe(struct platform_device *pdev)
> >>> orion_wdt.max_timeout = wdt_max_duration;
> >>> watchdog_init_timeout(&orion_wdt, heartbeat, &pdev->dev);
> >>>
> >>> + /* Let's make sure the watchdog is fully stopped */
> >>> + orion_wdt_stop(&orion_wdt);
> >>> +
> >>
> >> Actually we just had that in another driver, and I stumbled over it there.
> >>
> >> Problem with stopping the watchdog in probe unconditionally is that you can
> >> use it to defeat nowayout: unload the module, then load it again,
> >> and the watchdog is stopped even if nowayout is true.
> >>
> >
> > Hm... I see.
> >
> >> Is this really what you want ? Or, in other words, what is the problem
> >> you are trying to solve ?
> >>
> >
> > Well, this is related to the discussion about the bootloader not
> > reseting the watchdog properly, provoking spurious watchdog triggering.
> >
> > Jason Gunthorpe explained [1] that we needed a particular sequence:
> >
> > 1. Disable WDT
> > 2. Clear bridge
> > 3. Enable WDT
> >
> > We added the irq handling to satisfy (2), and the watchdog stop for (1).
> >
> > The watchdog stop was agreed specifically [2].
> >
> > Ideas?
> >
>
> Other drivers assume that if the watchdog is running, it is supposed
> to be running. The more common approach in such cases is to ping the
> watchdog once to give userspace more time to get ready, but leave
> it enabled. So you could check if the watchdog is enabled, and if
> it was enabled re-enable it after initialization is complete
> (and maybe log a message stating that the watchdog is enabled).
>
> If you don't want to do that, and if you are defeating nowayout
> on purpose to fix a problem with a broken bootloader,
> you should at least put in comment describing the problem you are
> trying to solve, and that you accept breaking nowayout with your fix.
>
I'm not fond of not having "nowayout" option on our driver, given I'm sure
it's a watchdog feature for a good reason.
On the other side, I can't see how can we distinguish a previously
and explicitly enabled watchdog, from a spurious enable by broken bootloader.
Jason, what do you say?
--
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH 21/21] ARM: Kirkwood: Remove DT support
From: Jason Cooper @ 2014-02-07 15:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207160954.69fbca38@skate>
On Fri, Feb 07, 2014 at 04:09:54PM +0100, Thomas Petazzoni wrote:
> Dear Jason Cooper,
>
> On Fri, 7 Feb 2014 10:03:06 -0500, Jason Cooper wrote:
>
> > Ideally, I'd prefer multi_v7 and multi_v5 for DT, and
> > {kirkwood,dove,orion5x,mv78xx0}_defconfig for non-DT legacy building.
> > The latter going away once we deprecate non-DT booting. There is a case
> > to be made for the arch-specific defconfigs, though.
> >
> > Currently (includes modules if configured, and dtbs);
> >
> > mvebu_defconfig 00:02:56
> > x86_64_defconfig 00:04:24
> > multi_v7_defconfig 00:04:05
> >
> > 1 minute and 9 seconds doesn't drastically change a bathroom break or
> > tea time ;-) But it is a 33% increase.
>
> I also like to have a more focused defconfig than multi_v7 for
> development.
>
> > If we want something leaner than multi_v7, how about
> > armada_370-xp_defconfig to replace the current mvebu_defconfig?
>
> Doesn't work for me: we're going to introduce soon the support for
> other mvebu ARMv7 SoC that are not Armada 370 nor XP, but that should
> be built as part of this.
>
> Why not mvebu_v7 and mvebu_v5 as I suggested? mvebu_v7 would build both
> Dove and Armada 370/XP (and the other ones we are going to introduce
> soon), mvebu_v5 would build Kirkwood (and possibly Orion5x once I find
> enough time to work on this platform).
Yeah, I can go with that, as long as Sebastian doesn't see a need for a
separate dove_defconfig in the long term (DT only). Sebastian?
> This way, ultimately we can simply remove kirkwood_defconfig and
> dove_defconfig, as soon as all legacy platforms have been either
> converted to DT, or removed.
Yep, the fewer builds I have to do per patch submission, the better.
thx,
Jason.
^ permalink raw reply
* [PATCH] clk: respect the clock dependencies in of_clk_init
From: Gregory CLEMENT @ 2014-02-07 15:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F4F502.2010703@elopez.com.ar>
On 07/02/2014 16:00, Emilio L?pez wrote:
> El 07/02/14 11:49, Gregory CLEMENT escribi?:
>> On 07/02/2014 15:43, Ezequiel Garcia wrote:
>>> On Fri, Feb 07, 2014 at 09:24:30AM -0500, Jason Cooper wrote:
>>>> On Fri, Feb 07, 2014 at 10:06:08AM -0300, Emilio L?pez wrote:
>>>>
>>>> [snip a great explanation]
>>>>
>>>> Guys, can I get some Tested-by's on this?
>>>>
>>>
>>> In case someone missed Emilio's comment about it, I gave his oneliner
>>> a test on A370 Reference Design. It worked just as well as Sebastian's.
>>
>> Well ok it's working but this patch is not better than Sebastian, it is
>> even worth. I don't think it is a good idea at all to totally ignore the
>> information given by the device tree.
>
> With a bit more work, you can replace the clk_get magic with a call to
> of_clk_get_parent_name() or similar to be able to keep overriding stuff
> from DT. This way it would completely match the behaviour on
> mvebu_coreclk_setup (default to "tclk", allow overriding with DT).
>
I think you didn't have a look on our implementation: the name of the clock
are created by the driver during the initialization. That's why we need that
the parent clock are initialized before the gating clock. I know that for the
sunxi clock you choose to list all your clock name in the device tree, but we
didn't make this choice on purpose. It is not as trivial as you suggested.
I didn't have a look on the atmel clocks, and I don't know if they have this
kind of issue, as they also have to deal with multiple parents, they may
have different issues.
Gregory
> Emilio
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH] i2c: mv64xxx: Fix locked bus when offload is selected but not used on a message
From: Jason Cooper @ 2014-02-07 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391770588-1344-1-git-send-email-gregory.clement@free-electrons.com>
On Fri, Feb 07, 2014 at 11:55:54AM +0100, Gregory CLEMENT wrote:
> Offload can be used only on regular transactions and for 1 to byte
> transfers. In the other cases we switch back to usual work flow.
>
> In this case we need to call mv64xxx_i2c_prepare_for_io() as this
> function is not used when we try to use offloading.
>
> This commit adds this missing call when offloading have failed in the
> MV64XXX_I2C_ACTION_OFFLOAD_SEND_START case.
>
> This fix the timeout seen when the the i2c driver try to access an
> address where the device is absent on the Armada XP bases board.
>
> Cc: stable at vger.kernel.org # v3.12+
> Fixes: 930ab3d403ae (i2c: mv64xxx: Add I2C Transaction Generator support)
>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> drivers/i2c/busses/i2c-mv64xxx.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
I'd like to get a few tested-by's on this before this is pushed. We've
had quite a bit of fixes this round :( Please test both multi_v7 and
mvebu defconfigs.
Kevin, I know you're busy with a lot more than us, but if you could
confirm that this fixes the bus hangs you reported, that would be great.
thx,
Jason.
>
> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
> index b8c5187b9ee0..a1700c62d955 100644
> --- a/drivers/i2c/busses/i2c-mv64xxx.c
> +++ b/drivers/i2c/busses/i2c-mv64xxx.c
> @@ -461,8 +461,15 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
> case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START:
> if (!mv64xxx_i2c_offload_msg(drv_data))
> break;
> - else
> + else {
> drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
> + /*
> + * Switch to the standard path, so we finally need to
> + * prepare the io that have not been done in
> + * mv64xxx_i2c_execute_msg
> + */
> + mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
> + }
> /* FALLTHRU */
> case MV64XXX_I2C_ACTION_SEND_START:
> writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
> --
> 1.8.1.2
>
^ permalink raw reply
* [PATCH 21/21] ARM: Kirkwood: Remove DT support
From: Thomas Petazzoni @ 2014-02-07 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207150306.GX8533@titan.lakedaemon.net>
Dear Jason Cooper,
On Fri, 7 Feb 2014 10:03:06 -0500, Jason Cooper wrote:
> Ideally, I'd prefer multi_v7 and multi_v5 for DT, and
> {kirkwood,dove,orion5x,mv78xx0}_defconfig for non-DT legacy building.
> The latter going away once we deprecate non-DT booting. There is a case
> to be made for the arch-specific defconfigs, though.
>
> Currently (includes modules if configured, and dtbs);
>
> mvebu_defconfig 00:02:56
> x86_64_defconfig 00:04:24
> multi_v7_defconfig 00:04:05
>
> 1 minute and 9 seconds doesn't drastically change a bathroom break or
> tea time ;-) But it is a 33% increase.
I also like to have a more focused defconfig than multi_v7 for
development.
> If we want something leaner than multi_v7, how about
> armada_370-xp_defconfig to replace the current mvebu_defconfig?
Doesn't work for me: we're going to introduce soon the support for
other mvebu ARMv7 SoC that are not Armada 370 nor XP, but that should
be built as part of this.
Why not mvebu_v7 and mvebu_v5 as I suggested? mvebu_v7 would build both
Dove and Armada 370/XP (and the other ones we are going to introduce
soon), mvebu_v5 would build Kirkwood (and possibly Orion5x once I find
enough time to work on this platform).
This way, ultimately we can simply remove kirkwood_defconfig and
dove_defconfig, as soon as all legacy platforms have been either
converted to DT, or removed.
Best regards,
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH v3 2/5] clk: sunxi: Add USB clock register defintions
From: Hans de Goede @ 2014-02-07 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207144441.GK3192@lukather>
Hi,
On 02/07/2014 03:44 PM, Maxime Ripard wrote:
> Hi,
>
> On Fri, Feb 07, 2014 at 03:32:30PM +0100, Hans de Goede wrote:
>> From: Roman Byshko <rbyshko@gmail.com>
>>
>> Add register definitions for the usb-clk register found on sun4i, sun5i and
>> sun7i SoCs.
>>
>> Signed-off-by: Roman Byshko <rbyshko@gmail.com>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>> Documentation/devicetree/bindings/clock/sunxi.txt | 5 +++++
>> drivers/clk/sunxi/clk-sunxi.c | 12 ++++++++++++
>> 2 files changed, 17 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
>> index 27f19f1..e368a86c 100644
>> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
>> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
>> @@ -38,6 +38,8 @@ Required properties:
>> "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
>> "allwinner,sun7i-a20-out-clk" - for the external output clocks
>> "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
>> + "allwinner,sun4i-usb-clk" - for usb gates + resets on A10 / A20
>
> I know I asked you otherwise, but since we're moving to sun4i-a10-*
> compatibles, can you do it here too ? :)
Sure can do, v4 coming up.
Regards,
Hans
^ permalink raw reply
* [PATCH 21/21] ARM: Kirkwood: Remove DT support
From: Jason Cooper @ 2014-02-07 15:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207093313.1a979a8f@skate>
On Fri, Feb 07, 2014 at 09:33:13AM +0100, Thomas Petazzoni wrote:
> Dear Andrew Lunn,
>
> On Fri, 7 Feb 2014 00:42:17 +0100, Andrew Lunn wrote:
> > Now that all the device tree support is in mach-mvebu, remove it from
> > mach-kirkwood.
> >
> > Regenerate kirkwood_defconfig, removing all DT support, and a couple
> > of other redundent options have been removed in the process.
> >
> > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> > ---
> > arch/arm/configs/kirkwood_defconfig | 6 -
>
> So after this series we have a mvebu_defconfig that only builds the
> ARMv7 platforms of mach-mvebu. I believe this may look strange to
> people looking at the code, seeing that Kirkwood DT support is in
> mach-mvebu, but that mvebu_defconfig doesn't work to build a Kirkwood
> kernel.
>
> I don't really have a solution, except maybe having mvebu_v7_defconfig
> and mvebu_v5_defconfig to build only the Marvell v7 and Marvell v5
> platforms.
Ideally, I'd prefer multi_v7 and multi_v5 for DT, and
{kirkwood,dove,orion5x,mv78xx0}_defconfig for non-DT legacy building.
The latter going away once we deprecate non-DT booting. There is a case
to be made for the arch-specific defconfigs, though.
Currently (includes modules if configured, and dtbs);
mvebu_defconfig 00:02:56
x86_64_defconfig 00:04:24
multi_v7_defconfig 00:04:05
1 minute and 9 seconds doesn't drastically change a bathroom break or
tea time ;-) But it is a 33% increase.
If we want something leaner than multi_v7, how about
armada_370-xp_defconfig to replace the current mvebu_defconfig?
kirkwood_defconfig could enable ARCH_KIRKWOOD and MACH_KIRKWOOD until we
remove legacy boot. Same with dove_defconfig and the others.
thx,
Jason.
^ permalink raw reply
* [PATCH] clk: respect the clock dependencies in of_clk_init
From: Emilio López @ 2014-02-07 15:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F4F279.6010006@free-electrons.com>
El 07/02/14 11:49, Gregory CLEMENT escribi?:
> On 07/02/2014 15:43, Ezequiel Garcia wrote:
>> On Fri, Feb 07, 2014 at 09:24:30AM -0500, Jason Cooper wrote:
>>> On Fri, Feb 07, 2014 at 10:06:08AM -0300, Emilio L?pez wrote:
>>>
>>> [snip a great explanation]
>>>
>>> Guys, can I get some Tested-by's on this?
>>>
>>
>> In case someone missed Emilio's comment about it, I gave his oneliner
>> a test on A370 Reference Design. It worked just as well as Sebastian's.
>
> Well ok it's working but this patch is not better than Sebastian, it is
> even worth. I don't think it is a good idea at all to totally ignore the
> information given by the device tree.
With a bit more work, you can replace the clk_get magic with a call to
of_clk_get_parent_name() or similar to be able to keep overriding stuff
from DT. This way it would completely match the behaviour on
mvebu_coreclk_setup (default to "tclk", allow overriding with DT).
Emilio
^ permalink raw reply
* [PATCH 8/8] tty/serial: at91: add dcd control via gpio
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
On sam9x5, the USART controller doesn't handle DTR/DSR/DCD/RI signals,
so we have to control them via GPIO.
This patch permits to use a GPIO to control the DCD signal.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
.../devicetree/bindings/serial/atmel-usart.txt | 3 ++
arch/arm/mach-at91/at91rm9200_devices.c | 5 +++
arch/arm/mach-at91/at91sam9260_devices.c | 7 ++++
arch/arm/mach-at91/at91sam9261_devices.c | 4 +++
arch/arm/mach-at91/at91sam9263_devices.c | 4 +++
arch/arm/mach-at91/at91sam9g45_devices.c | 5 +++
arch/arm/mach-at91/at91sam9rl_devices.c | 5 +++
drivers/tty/serial/atmel_serial.c | 38 ++++++++++++++++++++--
include/linux/platform_data/atmel.h | 1 +
9 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/serial/atmel-usart.txt
index 11d033649b19..4ff660e1487f 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/serial/atmel-usart.txt
@@ -23,6 +23,8 @@ Optional properties:
function pin for the USART DSR feature. If unsure, don't specify this property.
- ri-gpios: specify a GPIO for Ring line. It will use specified PIO instead of the peripheral
function pin for the USART Ring feature. If unsure, don't specify this property.
+- dcd-gpios: specify a GPIO for DCD line. It will use specified PIO instead of the peripheral
+ function pin for the USART DCD feature. If unsure, don't specify this property.
- add dma bindings for dma transfer:
- dmas: DMA specifier, consisting of a phandle to DMA controller node,
memory peripheral interface and USART DMA channel ID, FIFO configuration.
@@ -48,6 +50,7 @@ Example:
dtr-gpios = <&pioD 17 0>;
dsr-gpios = <&pioD 18 0>;
ri-gpios = <&pioD 19 0>;
+ dcd-gpios = <&pioD 20 0>;
};
- use DMA:
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 11c5c7f5b067..288421f38b42 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -927,6 +927,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -970,6 +971,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1025,6 +1027,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1081,6 +1084,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1129,6 +1133,7 @@ static struct atmel_uart_data uart3_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index f8ccdbe2bcbc..0e20ba04d43f 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -824,6 +824,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -867,6 +868,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -923,6 +925,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -971,6 +974,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1019,6 +1023,7 @@ static struct atmel_uart_data uart3_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
@@ -1067,6 +1072,7 @@ static struct atmel_uart_data uart4_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart4_dmamask = DMA_BIT_MASK(32);
@@ -1110,6 +1116,7 @@ static struct atmel_uart_data uart5_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart5_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index c40aa819cfac..d3d7a546db9b 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -885,6 +885,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -928,6 +929,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -976,6 +978,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1024,6 +1027,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 1da08465d952..5fcb2a0383d1 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -1329,6 +1329,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1372,6 +1373,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1420,6 +1422,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1468,6 +1471,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 4520d8f70cff..bd44970403e5 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1592,6 +1592,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1635,6 +1636,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1683,6 +1685,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1731,6 +1734,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1779,6 +1783,7 @@ static struct atmel_uart_data uart3_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 5916d65b6362..e43623dc1c9e 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -961,6 +961,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1004,6 +1005,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1060,6 +1062,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1108,6 +1111,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1156,6 +1160,7 @@ static struct atmel_uart_data uart3_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 9d47497713ab..926f77e6bde5 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -138,6 +138,8 @@ struct gpio_lines {
int dsr_irq;
int ri; /* optional Ring GPIO */
int ri_irq;
+ int dcd; /* optional DCD GPIO */
+ int dcd_irq;
};
/*
@@ -280,6 +282,13 @@ static unsigned int atmel_get_lines_status(struct uart_port *port)
status &= ~ATMEL_US_RI;
}
+ if (gpio_is_valid(atmel_port->gpio.dcd)) {
+ if (gpio_get_value(atmel_port->gpio.dcd))
+ status |= ATMEL_US_DCD;
+ else
+ status &= ~ATMEL_US_DCD;
+ }
+
return status;
}
@@ -503,7 +512,7 @@ static void atmel_stop_rx(struct uart_port *port)
static void atmel_enable_ms(struct uart_port *port)
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- uint32_t ier;
+ uint32_t ier = 0;
/*
* Interrupt should not be enabled twice
@@ -513,8 +522,6 @@ static void atmel_enable_ms(struct uart_port *port)
atmel_port->ms_irq_enabled = true;
- ier = ATMEL_US_DCDIC;
-
if (atmel_port->gpio.cts_irq != INVALID_IRQ)
enable_irq(atmel_port->gpio.cts_irq);
else
@@ -530,6 +537,11 @@ static void atmel_enable_ms(struct uart_port *port)
else
ier |= ATMEL_US_RIIC;
+ if (atmel_port->gpio.dcd_irq != INVALID_IRQ)
+ enable_irq(atmel_port->gpio.dcd_irq);
+ else
+ ier |= ATMEL_US_DCDIC;
+
UART_PUT_IER(port, ier);
}
@@ -1142,6 +1154,10 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
(irq == atmel_port->gpio.ri_irq))
pending |= ATMEL_US_RIIC;
+ if ((irq != INVALID_IRQ) &&
+ (irq == atmel_port->gpio.dcd_irq))
+ pending |= ATMEL_US_DCDIC;
+
gpio_handled = true;
}
if (!pending)
@@ -1685,6 +1701,11 @@ static int atmel_startup(struct uart_port *port)
if (retval)
goto free_dsr_irq;
+ retval = atmel_request_gpio_irq(port, atmel_port->gpio.dcd_irq,
+ "atmel_dcd_irq");
+ if (retval)
+ goto free_ri_irq;
+
/*
* Initialize DMA (if necessary)
*/
@@ -1750,6 +1771,9 @@ static int atmel_startup(struct uart_port *port)
return 0;
+free_ri_irq:
+ free_irq(atmel_port->gpio.ri_irq, port);
+
free_dsr_irq:
free_irq(atmel_port->gpio.dsr_irq, port);
@@ -1816,6 +1840,8 @@ static void atmel_shutdown(struct uart_port *port)
free_irq(atmel_port->gpio.dsr_irq, port);
if (atmel_port->gpio.ri_irq != INVALID_IRQ)
free_irq(atmel_port->gpio.ri_irq, port);
+ if (atmel_port->gpio.dcd_irq != INVALID_IRQ)
+ free_irq(atmel_port->gpio.dcd_irq, port);
atmel_port->ms_irq_enabled = false;
}
@@ -2525,6 +2551,8 @@ static int atmel_init_gpios(struct atmel_uart_port *atmel_port,
"DSR", &atmel_port->gpio.dsr_irq);
ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.ri,
"RI", &atmel_port->gpio.ri_irq);
+ ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.dcd,
+ "DCD", &atmel_port->gpio.dcd_irq);
return ret;
}
@@ -2568,21 +2596,25 @@ static int atmel_serial_probe(struct platform_device *pdev)
port->gpio.dtr = -EINVAL;
port->gpio.dsr = -EINVAL;
port->gpio.ri = -EINVAL;
+ port->gpio.dcd = -EINVAL;
port->gpio.cts_irq = INVALID_IRQ;
port->gpio.dsr_irq = INVALID_IRQ;
port->gpio.ri_irq = INVALID_IRQ;
+ port->gpio.dcd_irq = INVALID_IRQ;
if (pdata) {
port->gpio.rts = pdata->rts_gpio;
port->gpio.cts = pdata->cts_gpio;
port->gpio.dtr = pdata->dtr_gpio;
port->gpio.dsr = pdata->dsr_gpio;
port->gpio.ri = pdata->ri_gpio;
+ port->gpio.dcd = pdata->dcd_gpio;
} else if (np) {
port->gpio.rts = of_get_named_gpio(np, "rts-gpios", 0);
port->gpio.cts = of_get_named_gpio(np, "cts-gpios", 0);
port->gpio.dtr = of_get_named_gpio(np, "dtr-gpios", 0);
port->gpio.dsr = of_get_named_gpio(np, "dsr-gpios", 0);
port->gpio.ri = of_get_named_gpio(np, "ri-gpios", 0);
+ port->gpio.dcd = of_get_named_gpio(np, "dcd-gpios", 0);
}
ret = atmel_init_gpios(port, pdev);
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index ce6ca1b8aef3..565c5c693c7f 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -88,6 +88,7 @@ struct atmel_uart_data {
int cts_gpio; /* optional CTS GPIO */
int dtr_gpio; /* optional DTR GPIO */
int dsr_gpio; /* optional DSR GPIO */
+ int dcd_gpio; /* optional DCD GPIO */
int ri_gpio; /* optional Ring GPIO */
};
--
1.8.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox