aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/sunxi/patches-4.1/171-musb-add-support-for-a31.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/sunxi/patches-4.1/171-musb-add-support-for-a31.patch')
-rw-r--r--target/linux/sunxi/patches-4.1/171-musb-add-support-for-a31.patch162
1 files changed, 162 insertions, 0 deletions
diff --git a/target/linux/sunxi/patches-4.1/171-musb-add-support-for-a31.patch b/target/linux/sunxi/patches-4.1/171-musb-add-support-for-a31.patch
new file mode 100644
index 0000000..af958f2
--- /dev/null
+++ b/target/linux/sunxi/patches-4.1/171-musb-add-support-for-a31.patch
@@ -0,0 +1,162 @@
+From 132e23775779cc895c37f7883c33a60a1a8a7cdd Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 8 Jul 2015 16:41:39 +0200
+Subject: [PATCH] usb: musb: sunxi: Add support for musb controller in A31 SoC
+
+The A31 SoC uses the same musb controller as found in earlier SoCs, but it
+is hooked up slightly different. Its SRAM is private and no longer controlled
+through the SRAM controller, and its reset is controlled via a separate
+reset controller. This commit adds support for this setup.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+---
+ .../bindings/usb/allwinner,sun4i-a10-musb.txt | 3 +-
+ drivers/usb/musb/sunxi.c | 50 +++++++++++++++++++---
+ 2 files changed, 46 insertions(+), 7 deletions(-)
+
+--- a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
++++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
+@@ -2,9 +2,10 @@ Allwinner sun4i A10 musb DRC/OTG control
+ -------------------------------------------
+
+ Required properties:
+- - compatible : "allwinner,sun4i-a10-musb"
++ - compatible : "allwinner,sun4i-a10-musb" or "allwinner,sun6i-a31-musb"
+ - reg : mmio address range of the musb controller
+ - clocks : clock specifier for the musb controller ahb gate clock
++ - reset : reset specifier for the ahb reset (A31 and newer only)
+ - interrupts : interrupt to which the musb controller is connected
+ - interrupt-names : must be "mc"
+ - phys : phy specifier for the otg phy
+--- a/drivers/usb/musb/sunxi.c
++++ b/drivers/usb/musb/sunxi.c
+@@ -26,6 +26,7 @@
+ #include <linux/of.h>
+ #include <linux/phy/phy-sun4i-usb.h>
+ #include <linux/platform_device.h>
++#include <linux/reset.h>
+ #include <linux/soc/sunxi/sunxi_sram.h>
+ #include <linux/usb/musb.h>
+ #include <linux/usb/of.h>
+@@ -70,6 +71,8 @@
+ #define SUNXI_MUSB_FL_HOSTMODE_PEND 2
+ #define SUNXI_MUSB_FL_VBUS_ON 3
+ #define SUNXI_MUSB_FL_PHY_ON 4
++#define SUNXI_MUSB_FL_HAS_SRAM 5
++#define SUNXI_MUSB_FL_HAS_RESET 6
+
+ /* Our read/write methods need access and do not get passed in a musb ref :| */
+ static struct musb *sunxi_musb;
+@@ -78,6 +81,7 @@ struct sunxi_glue {
+ struct device *dev;
+ struct platform_device *musb;
+ struct clk *clk;
++ struct reset_control *rst;
+ struct phy *phy;
+ struct platform_device *usb_phy;
+ struct usb_phy *xceiv;
+@@ -229,14 +233,22 @@ static int sunxi_musb_init(struct musb *
+ musb->phy = glue->phy;
+ musb->xceiv = glue->xceiv;
+
+- ret = sunxi_sram_claim(musb->controller->parent);
+- if (ret)
+- return ret;
++ if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags)) {
++ ret = sunxi_sram_claim(musb->controller->parent);
++ if (ret)
++ return ret;
++ }
+
+ ret = clk_prepare_enable(glue->clk);
+ if (ret)
+ goto error_sram_release;
+
++ if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) {
++ ret = reset_control_deassert(glue->rst);
++ if (ret)
++ goto error_clk_disable;
++ }
++
+ writeb(SUNXI_MUSB_VEND0_PIO_MODE, musb->mregs + SUNXI_MUSB_VEND0);
+
+ /* Register notifier before calling phy_init() */
+@@ -244,7 +256,7 @@ static int sunxi_musb_init(struct musb *
+ ret = extcon_register_notifier(glue->extcon, EXTCON_USB_HOST,
+ &glue->host_nb);
+ if (ret)
+- goto error_clk_disable;
++ goto error_reset_assert;
+ }
+
+ ret = phy_init(glue->phy);
+@@ -273,10 +285,14 @@ error_unregister_notifier:
+ if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
+ extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST,
+ &glue->host_nb);
++error_reset_assert:
++ if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags))
++ reset_control_assert(glue->rst);
+ error_clk_disable:
+ clk_disable_unprepare(glue->clk);
+ error_sram_release:
+- sunxi_sram_release(musb->controller->parent);
++ if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags))
++ sunxi_sram_release(musb->controller->parent);
+ return ret;
+ }
+
+@@ -296,8 +312,12 @@ static int sunxi_musb_exit(struct musb *
+ extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST,
+ &glue->host_nb);
+
++ if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags))
++ reset_control_assert(glue->rst);
++
+ clk_disable_unprepare(glue->clk);
+- sunxi_sram_release(musb->controller->parent);
++ if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags))
++ sunxi_sram_release(musb->controller->parent);
+
+ return 0;
+ }
+@@ -617,6 +637,12 @@ static int sunxi_musb_probe(struct platf
+ INIT_WORK(&glue->work, sunxi_musb_work);
+ glue->host_nb.notifier_call = sunxi_musb_host_notifier;
+
++ if (of_device_is_compatible(np, "allwinner,sun4i-a10-musb"))
++ set_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags);
++
++ if (of_device_is_compatible(np, "allwinner,sun6i-a31-musb"))
++ set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
++
+ glue->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(glue->clk)) {
+ dev_err(&pdev->dev, "Error getting clock: %ld\n",
+@@ -624,6 +650,17 @@ static int sunxi_musb_probe(struct platf
+ return PTR_ERR(glue->clk);
+ }
+
++ if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) {
++ glue->rst = devm_reset_control_get(&pdev->dev, NULL);
++ if (IS_ERR(glue->rst)) {
++ if (PTR_ERR(glue->rst) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++ dev_err(&pdev->dev, "Error getting reset %ld\n",
++ PTR_ERR(glue->rst));
++ return PTR_ERR(glue->rst);
++ }
++ }
++
+ glue->phy = devm_phy_get(&pdev->dev, "usb");
+ if (IS_ERR(glue->phy)) {
+ if (PTR_ERR(glue->phy) == -EPROBE_DEFER)
+@@ -685,6 +722,7 @@ static int sunxi_musb_remove(struct plat
+
+ static const struct of_device_id sunxi_musb_match[] = {
+ { .compatible = "allwinner,sun4i-a10-musb", },
++ { .compatible = "allwinner,sun6i-a31-musb", },
+ {}
+ };
+