diff options
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.patch | 166 |
1 files changed, 166 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 0000000000..374dbc4ddb --- /dev/null +++ b/target/linux/sunxi/patches-4.1/171-musb-add-support-for-a31.patch @@ -0,0 +1,166 @@ +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(-) + +diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt +index 9254a6c..fde180b 100644 +--- 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 controller + ------------------------------------------- + + 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 +diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c +index 00d7248..df2f75e 100644 +--- 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) + 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 *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 @@ static int sunxi_musb_init(struct musb *musb) + 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 *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 platform_device *pdev) + 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 platform_device *pdev) + 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 platform_device *pdev) + + static const struct of_device_id sunxi_musb_match[] = { + { .compatible = "allwinner,sun4i-a10-musb", }, ++ { .compatible = "allwinner,sun6i-a31-musb", }, + {} + }; + |