diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-10 07:47:50 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-10 07:47:50 -0400 |
| commit | 2aebe3f3b20724e09ec76b196e16404d1ea573d9 (patch) | |
| tree | ef667cb786a58d3bb2639ad5c488e5bac501defa | |
| parent | c8d1bc12c7986c166bd3504213d9df2bc11ad7d6 (diff) | |
| parent | e95cf393d2097a7744f98de1c7936fcbde0843e3 (diff) | |
Merge tag 'for-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-next
Kishon writes:
New Features
============
*) Add driver for USB PHYs on sun9i
*) Add driver for USB PHY on dm816x
*) Modified exynos5-usbdrd driver to add support for Exynos5433 SoC
Fixes
=====
*) Fix power_on/power_off failure paths in some drivers
*) Make miphy365x use generic PHY type constants
*) Fix build errors due to missing export symbols in qcom-ufs driver
*) Make all the functions return proper error values
Cleanups
========
*) use PTR_ERR_OR_ZERO to simplify code
*) use devm_kcalloc instead of devm_kzalloc with multiply
*) remove un-necessary ifdef CONFIG_OF
26 files changed, 655 insertions, 110 deletions
diff --git a/Documentation/devicetree/bindings/phy/dm816x-phy.txt b/Documentation/devicetree/bindings/phy/dm816x-phy.txt new file mode 100644 index 000000000000..2fe3d11d063d --- /dev/null +++ b/Documentation/devicetree/bindings/phy/dm816x-phy.txt | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | Device tree binding documentation for am816x USB PHY | ||
| 2 | ========================= | ||
| 3 | |||
| 4 | Required properties: | ||
| 5 | - compatible : should be "ti,dm816x-usb-phy" | ||
| 6 | - reg : offset and length of the PHY register set. | ||
| 7 | - reg-names : name for the phy registers | ||
| 8 | - clocks : phandle to the clock | ||
| 9 | - clock-names : name of the clock | ||
| 10 | - syscon: phandle for the syscon node to access misc registers | ||
| 11 | - #phy-cells : from the generic PHY bindings, must be 1 | ||
| 12 | - syscon: phandle for the syscon node to access misc registers | ||
| 13 | |||
| 14 | Example: | ||
| 15 | |||
| 16 | usb_phy0: usb-phy@20 { | ||
| 17 | compatible = "ti,dm8168-usb-phy"; | ||
| 18 | reg = <0x20 0x8>; | ||
| 19 | reg-names = "phy"; | ||
| 20 | clocks = <&main_fapll 6>; | ||
| 21 | clock-names = "refclk"; | ||
| 22 | #phy-cells = <0>; | ||
| 23 | syscon = <&scm_conf>; | ||
| 24 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt index 9802d5d911aa..8772900e056a 100644 --- a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt +++ b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt | |||
| @@ -20,8 +20,8 @@ Required nodes : A sub-node is required for each channel the controller | |||
| 20 | Required properties (port (child) node): | 20 | Required properties (port (child) node): |
| 21 | - #phy-cells : Should be 1 (See second example) | 21 | - #phy-cells : Should be 1 (See second example) |
| 22 | Cell after port phandle is device type from: | 22 | Cell after port phandle is device type from: |
| 23 | - MIPHY_TYPE_SATA | 23 | - PHY_TYPE_SATA |
| 24 | - MIPHY_TYPE_PCI | 24 | - PHY_TYPE_PCI |
| 25 | - reg : Address and length of register sets for each device in | 25 | - reg : Address and length of register sets for each device in |
| 26 | "reg-names" | 26 | "reg-names" |
| 27 | - reg-names : The names of the register addresses corresponding to the | 27 | - reg-names : The names of the register addresses corresponding to the |
| @@ -68,10 +68,10 @@ property, containing a phandle to the phy port node and a device type. | |||
| 68 | 68 | ||
| 69 | Example: | 69 | Example: |
| 70 | 70 | ||
| 71 | #include <dt-bindings/phy/phy-miphy365x.h> | 71 | #include <dt-bindings/phy/phy.h> |
| 72 | 72 | ||
| 73 | sata0: sata@fe380000 { | 73 | sata0: sata@fe380000 { |
| 74 | ... | 74 | ... |
| 75 | phys = <&phy_port0 MIPHY_TYPE_SATA>; | 75 | phys = <&phy_port0 PHY_TYPE_SATA>; |
| 76 | ... | 76 | ... |
| 77 | }; | 77 | }; |
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 91e38cfe1f8f..60c6f2a633e0 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt | |||
| @@ -128,6 +128,7 @@ Required properties: | |||
| 128 | - compatible : Should be set to one of the following supported values: | 128 | - compatible : Should be set to one of the following supported values: |
| 129 | - "samsung,exynos5250-usbdrd-phy" - for exynos5250 SoC, | 129 | - "samsung,exynos5250-usbdrd-phy" - for exynos5250 SoC, |
| 130 | - "samsung,exynos5420-usbdrd-phy" - for exynos5420 SoC. | 130 | - "samsung,exynos5420-usbdrd-phy" - for exynos5420 SoC. |
| 131 | - "samsung,exynos5433-usbdrd-phy" - for exynos5433 SoC. | ||
| 131 | - "samsung,exynos7-usbdrd-phy" - for exynos7 SoC. | 132 | - "samsung,exynos7-usbdrd-phy" - for exynos7 SoC. |
| 132 | - reg : Register offset and length of USB DRD PHY register set; | 133 | - reg : Register offset and length of USB DRD PHY register set; |
| 133 | - clocks: Clock IDs array as required by the controller | 134 | - clocks: Clock IDs array as required by the controller |
| @@ -139,7 +140,7 @@ Required properties: | |||
| 139 | PHY operations, associated by phy name. It is used to | 140 | PHY operations, associated by phy name. It is used to |
| 140 | determine bit values for clock settings register. | 141 | determine bit values for clock settings register. |
| 141 | For Exynos5420 this is given as 'sclk_usbphy30' in CMU. | 142 | For Exynos5420 this is given as 'sclk_usbphy30' in CMU. |
| 142 | - optional clocks: Exynos7 SoC has now following additional | 143 | - optional clocks: Exynos5433 & Exynos7 SoC has now following additional |
| 143 | gate clocks available: | 144 | gate clocks available: |
| 144 | - phy_pipe: for PIPE3 phy | 145 | - phy_pipe: for PIPE3 phy |
| 145 | - phy_utmi: for UTMI+ phy | 146 | - phy_utmi: for UTMI+ phy |
diff --git a/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt new file mode 100644 index 000000000000..1cca85c709d1 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | Allwinner sun9i USB PHY | ||
| 2 | ----------------------- | ||
| 3 | |||
| 4 | Required properties: | ||
| 5 | - compatible : should be one of | ||
| 6 | * allwinner,sun9i-a80-usb-phy | ||
| 7 | - reg : a list of offset + length pairs | ||
| 8 | - #phy-cells : from the generic phy bindings, must be 0 | ||
| 9 | - phy_type : "hsic" for HSIC usage; | ||
| 10 | other values or absence of this property indicates normal USB | ||
| 11 | - clocks : phandle + clock specifier for the phy clocks | ||
| 12 | - clock-names : depending on the "phy_type" property, | ||
| 13 | * "phy" for normal USB | ||
| 14 | * "hsic_480M", "hsic_12M" for HSIC | ||
| 15 | - resets : a list of phandle + reset specifier pairs | ||
| 16 | - reset-names : depending on the "phy_type" property, | ||
| 17 | * "phy" for normal USB | ||
| 18 | * "hsic" for HSIC | ||
| 19 | |||
| 20 | Optional Properties: | ||
| 21 | - phy-supply : from the generic phy bindings, a phandle to a regulator that | ||
| 22 | provides power to VBUS. | ||
| 23 | |||
| 24 | It is recommended to list all clocks and resets available. | ||
| 25 | The driver will only use those matching the phy_type. | ||
| 26 | |||
| 27 | Example: | ||
| 28 | usbphy1: phy@00a01800 { | ||
| 29 | compatible = "allwinner,sun9i-a80-usb-phy"; | ||
| 30 | reg = <0x00a01800 0x4>; | ||
| 31 | clocks = <&usb_phy_clk 2>, <&usb_phy_clk 10>, | ||
| 32 | <&usb_phy_clk 3>; | ||
| 33 | clock-names = "hsic_480M", "hsic_12M", "phy"; | ||
| 34 | resets = <&usb_phy_clk 18>, <&usb_phy_clk 19>; | ||
| 35 | reset-names = "hsic", "phy"; | ||
| 36 | status = "disabled"; | ||
| 37 | #phy-cells = <0>; | ||
| 38 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index c3549da27ca7..728a80f75f62 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1468,6 +1468,8 @@ F: drivers/clocksource/arm_global_timer.c | |||
| 1468 | F: drivers/i2c/busses/i2c-st.c | 1468 | F: drivers/i2c/busses/i2c-st.c |
| 1469 | F: drivers/media/rc/st_rc.c | 1469 | F: drivers/media/rc/st_rc.c |
| 1470 | F: drivers/mmc/host/sdhci-st.c | 1470 | F: drivers/mmc/host/sdhci-st.c |
| 1471 | F: drivers/phy/phy-miphy28lp.c | ||
| 1472 | F: drivers/phy/phy-miphy365x.c | ||
| 1471 | F: drivers/phy/phy-stih407-usb.c | 1473 | F: drivers/phy/phy-stih407-usb.c |
| 1472 | F: drivers/phy/phy-stih41x-usb.c | 1474 | F: drivers/phy/phy-stih41x-usb.c |
| 1473 | F: drivers/pinctrl/pinctrl-st.c | 1475 | F: drivers/pinctrl/pinctrl-st.c |
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi index ea28ebadab1a..eeb7afecbbe6 100644 --- a/arch/arm/boot/dts/stih416.dtsi +++ b/arch/arm/boot/dts/stih416.dtsi | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "stih416-clock.dtsi" | 10 | #include "stih416-clock.dtsi" |
| 11 | #include "stih416-pinctrl.dtsi" | 11 | #include "stih416-pinctrl.dtsi" |
| 12 | 12 | ||
| 13 | #include <dt-bindings/phy/phy-miphy365x.h> | 13 | #include <dt-bindings/phy/phy.h> |
| 14 | #include <dt-bindings/interrupt-controller/arm-gic.h> | 14 | #include <dt-bindings/interrupt-controller/arm-gic.h> |
| 15 | #include <dt-bindings/reset-controller/stih416-resets.h> | 15 | #include <dt-bindings/reset-controller/stih416-resets.h> |
| 16 | / { | 16 | / { |
| @@ -306,7 +306,7 @@ | |||
| 306 | reg = <0xfe380000 0x1000>; | 306 | reg = <0xfe380000 0x1000>; |
| 307 | interrupts = <GIC_SPI 157 IRQ_TYPE_NONE>; | 307 | interrupts = <GIC_SPI 157 IRQ_TYPE_NONE>; |
| 308 | interrupt-names = "hostc"; | 308 | interrupt-names = "hostc"; |
| 309 | phys = <&phy_port0 MIPHY_TYPE_SATA>; | 309 | phys = <&phy_port0 PHY_TYPE_SATA>; |
| 310 | phy-names = "sata-phy"; | 310 | phy-names = "sata-phy"; |
| 311 | resets = <&powerdown STIH416_SATA0_POWERDOWN>, | 311 | resets = <&powerdown STIH416_SATA0_POWERDOWN>, |
| 312 | <&softreset STIH416_SATA0_SOFTRESET>; | 312 | <&softreset STIH416_SATA0_SOFTRESET>; |
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 2962de205ba7..a53bd5b52df9 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
| @@ -35,6 +35,13 @@ config ARMADA375_USBCLUSTER_PHY | |||
| 35 | depends on OF | 35 | depends on OF |
| 36 | select GENERIC_PHY | 36 | select GENERIC_PHY |
| 37 | 37 | ||
| 38 | config PHY_DM816X_USB | ||
| 39 | tristate "TI dm816x USB PHY driver" | ||
| 40 | depends on ARCH_OMAP2PLUS | ||
| 41 | select GENERIC_PHY | ||
| 42 | help | ||
| 43 | Enable this for dm816x USB to work. | ||
| 44 | |||
| 38 | config PHY_EXYNOS_MIPI_VIDEO | 45 | config PHY_EXYNOS_MIPI_VIDEO |
| 39 | tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" | 46 | tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" |
| 40 | depends on HAS_IOMEM | 47 | depends on HAS_IOMEM |
| @@ -174,6 +181,17 @@ config PHY_SUN4I_USB | |||
| 174 | This driver controls the entire USB PHY block, both the USB OTG | 181 | This driver controls the entire USB PHY block, both the USB OTG |
| 175 | parts, as well as the 2 regular USB 2 host PHYs. | 182 | parts, as well as the 2 regular USB 2 host PHYs. |
| 176 | 183 | ||
| 184 | config PHY_SUN9I_USB | ||
| 185 | tristate "Allwinner sun9i SoC USB PHY driver" | ||
| 186 | depends on ARCH_SUNXI && HAS_IOMEM && OF | ||
| 187 | depends on RESET_CONTROLLER | ||
| 188 | select GENERIC_PHY | ||
| 189 | help | ||
| 190 | Enable this to support the transceiver that is part of Allwinner | ||
| 191 | sun9i SoCs. | ||
| 192 | |||
| 193 | This driver controls each individual USB 2 host PHY. | ||
| 194 | |||
| 177 | config PHY_SAMSUNG_USB2 | 195 | config PHY_SAMSUNG_USB2 |
| 178 | tristate "Samsung USB 2.0 PHY driver" | 196 | tristate "Samsung USB 2.0 PHY driver" |
| 179 | depends on HAS_IOMEM | 197 | depends on HAS_IOMEM |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index f080e1bb2a74..f12625178780 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | obj-$(CONFIG_GENERIC_PHY) += phy-core.o | 5 | obj-$(CONFIG_GENERIC_PHY) += phy-core.o |
| 6 | obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o | 6 | obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o |
| 7 | obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o | 7 | obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o |
| 8 | obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o | ||
| 8 | obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o | 9 | obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o |
| 9 | obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o | 10 | obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o |
| 10 | obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o | 11 | obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o |
| @@ -20,6 +21,7 @@ obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o | |||
| 20 | obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o | 21 | obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o |
| 21 | obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o | 22 | obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o |
| 22 | obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o | 23 | obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o |
| 24 | obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o | ||
| 23 | obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o | 25 | obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o |
| 24 | phy-exynos-usb2-y += phy-samsung-usb2.o | 26 | phy-exynos-usb2-y += phy-samsung-usb2.o |
| 25 | phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o | 27 | phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o |
diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c index 099eee8851e5..6f3e06d687de 100644 --- a/drivers/phy/phy-berlin-sata.c +++ b/drivers/phy/phy-berlin-sata.c | |||
| @@ -218,7 +218,7 @@ static int phy_berlin_sata_probe(struct platform_device *pdev) | |||
| 218 | if (priv->nphys == 0) | 218 | if (priv->nphys == 0) |
| 219 | return -ENODEV; | 219 | return -ENODEV; |
| 220 | 220 | ||
| 221 | priv->phys = devm_kzalloc(dev, priv->nphys * sizeof(*priv->phys), | 221 | priv->phys = devm_kcalloc(dev, priv->nphys, sizeof(*priv->phys), |
| 222 | GFP_KERNEL); | 222 | GFP_KERNEL); |
| 223 | if (!priv->phys) | 223 | if (!priv->phys) |
| 224 | return -ENOMEM; | 224 | return -ENOMEM; |
diff --git a/drivers/phy/phy-berlin-usb.c b/drivers/phy/phy-berlin-usb.c index c8a8d53a6ece..c6fc95b53083 100644 --- a/drivers/phy/phy-berlin-usb.c +++ b/drivers/phy/phy-berlin-usb.c | |||
| @@ -103,9 +103,6 @@ | |||
| 103 | #define MODE_TEST_EN BIT(11) | 103 | #define MODE_TEST_EN BIT(11) |
| 104 | #define ANA_TEST_DC_CTRL(x) ((x) << 12) | 104 | #define ANA_TEST_DC_CTRL(x) ((x) << 12) |
| 105 | 105 | ||
| 106 | #define to_phy_berlin_usb_priv(p) \ | ||
| 107 | container_of((p), struct phy_berlin_usb_priv, phy) | ||
| 108 | |||
| 109 | static const u32 phy_berlin_pll_dividers[] = { | 106 | static const u32 phy_berlin_pll_dividers[] = { |
| 110 | /* Berlin 2 */ | 107 | /* Berlin 2 */ |
| 111 | CLK_REF_DIV(0xc) | FEEDBACK_CLK_DIV(0x54), | 108 | CLK_REF_DIV(0xc) | FEEDBACK_CLK_DIV(0x54), |
| @@ -115,14 +112,13 @@ static const u32 phy_berlin_pll_dividers[] = { | |||
| 115 | 112 | ||
| 116 | struct phy_berlin_usb_priv { | 113 | struct phy_berlin_usb_priv { |
| 117 | void __iomem *base; | 114 | void __iomem *base; |
| 118 | struct phy *phy; | ||
| 119 | struct reset_control *rst_ctrl; | 115 | struct reset_control *rst_ctrl; |
| 120 | u32 pll_divider; | 116 | u32 pll_divider; |
| 121 | }; | 117 | }; |
| 122 | 118 | ||
| 123 | static int phy_berlin_usb_power_on(struct phy *phy) | 119 | static int phy_berlin_usb_power_on(struct phy *phy) |
| 124 | { | 120 | { |
| 125 | struct phy_berlin_usb_priv *priv = dev_get_drvdata(phy->dev.parent); | 121 | struct phy_berlin_usb_priv *priv = phy_get_drvdata(phy); |
| 126 | 122 | ||
| 127 | reset_control_reset(priv->rst_ctrl); | 123 | reset_control_reset(priv->rst_ctrl); |
| 128 | 124 | ||
| @@ -175,6 +171,7 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) | |||
| 175 | of_match_device(phy_berlin_sata_of_match, &pdev->dev); | 171 | of_match_device(phy_berlin_sata_of_match, &pdev->dev); |
| 176 | struct phy_berlin_usb_priv *priv; | 172 | struct phy_berlin_usb_priv *priv; |
| 177 | struct resource *res; | 173 | struct resource *res; |
| 174 | struct phy *phy; | ||
| 178 | struct phy_provider *phy_provider; | 175 | struct phy_provider *phy_provider; |
| 179 | 176 | ||
| 180 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 177 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| @@ -192,20 +189,18 @@ static int phy_berlin_usb_probe(struct platform_device *pdev) | |||
| 192 | 189 | ||
| 193 | priv->pll_divider = *((u32 *)match->data); | 190 | priv->pll_divider = *((u32 *)match->data); |
| 194 | 191 | ||
| 195 | priv->phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops); | 192 | phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops); |
| 196 | if (IS_ERR(priv->phy)) { | 193 | if (IS_ERR(phy)) { |
| 197 | dev_err(&pdev->dev, "failed to create PHY\n"); | 194 | dev_err(&pdev->dev, "failed to create PHY\n"); |
| 198 | return PTR_ERR(priv->phy); | 195 | return PTR_ERR(phy); |
| 199 | } | 196 | } |
| 200 | 197 | ||
| 201 | platform_set_drvdata(pdev, priv); | 198 | platform_set_drvdata(pdev, priv); |
| 199 | phy_set_drvdata(phy, priv); | ||
| 202 | 200 | ||
| 203 | phy_provider = | 201 | phy_provider = |
| 204 | devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); | 202 | devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); |
| 205 | if (IS_ERR(phy_provider)) | 203 | return PTR_ERR_OR_ZERO(phy_provider); |
| 206 | return PTR_ERR(phy_provider); | ||
| 207 | |||
| 208 | return 0; | ||
| 209 | } | 204 | } |
| 210 | 205 | ||
| 211 | static struct platform_driver phy_berlin_usb_driver = { | 206 | static struct platform_driver phy_berlin_usb_driver = { |
diff --git a/drivers/phy/phy-dm816x-usb.c b/drivers/phy/phy-dm816x-usb.c new file mode 100644 index 000000000000..7b42555ddd51 --- /dev/null +++ b/drivers/phy/phy-dm816x-usb.c | |||
| @@ -0,0 +1,290 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or | ||
| 3 | * modify it under the terms of the GNU General Public License as | ||
| 4 | * published by the Free Software Foundation version 2. | ||
| 5 | * | ||
| 6 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
| 7 | * kind, whether express or implied; without even the implied warranty | ||
| 8 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 9 | * GNU General Public License for more details. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/regmap.h> | ||
| 15 | |||
| 16 | #include <linux/slab.h> | ||
| 17 | #include <linux/of.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | #include <linux/usb/phy_companion.h> | ||
| 20 | #include <linux/clk.h> | ||
| 21 | #include <linux/err.h> | ||
| 22 | #include <linux/pm_runtime.h> | ||
| 23 | #include <linux/delay.h> | ||
| 24 | #include <linux/phy/phy.h> | ||
| 25 | #include <linux/of_platform.h> | ||
| 26 | |||
| 27 | #include <linux/mfd/syscon.h> | ||
| 28 | |||
| 29 | /* | ||
| 30 | * TRM has two sets of USB_CTRL registers.. The correct register bits | ||
| 31 | * are in TRM section 24.9.8.2 USB_CTRL Register. The TRM documents the | ||
| 32 | * phy as being SR70LX Synopsys USB 2.0 OTG nanoPHY. It also seems at | ||
| 33 | * least dm816x rev c ignores writes to USB_CTRL register, but the TI | ||
| 34 | * kernel is writing to those so it's possible that later revisions | ||
| 35 | * have worknig USB_CTRL register. | ||
| 36 | * | ||
| 37 | * Also note that At least USB_CTRL register seems to be dm816x specific | ||
| 38 | * according to the TRM. It's possible that USBPHY_CTRL is more generic, | ||
| 39 | * but that would have to be checked against the SR70LX documentation | ||
| 40 | * which does not seem to be publicly available. | ||
| 41 | * | ||
| 42 | * Finally, the phy on dm814x and am335x is different from dm816x. | ||
| 43 | */ | ||
| 44 | #define DM816X_USB_CTRL_PHYCLKSRC BIT(8) /* 1 = PLL ref clock */ | ||
| 45 | #define DM816X_USB_CTRL_PHYSLEEP1 BIT(1) /* Enable the first phy */ | ||
| 46 | #define DM816X_USB_CTRL_PHYSLEEP0 BIT(0) /* Enable the second phy */ | ||
| 47 | |||
| 48 | #define DM816X_USBPHY_CTRL_TXRISETUNE 1 | ||
| 49 | #define DM816X_USBPHY_CTRL_TXVREFTUNE 0xc | ||
| 50 | #define DM816X_USBPHY_CTRL_TXPREEMTUNE 0x2 | ||
| 51 | |||
| 52 | struct dm816x_usb_phy { | ||
| 53 | struct regmap *syscon; | ||
| 54 | struct device *dev; | ||
| 55 | unsigned int instance; | ||
| 56 | struct clk *refclk; | ||
| 57 | struct usb_phy phy; | ||
| 58 | unsigned int usb_ctrl; /* Shared between phy0 and phy1 */ | ||
| 59 | unsigned int usbphy_ctrl; | ||
| 60 | }; | ||
| 61 | |||
| 62 | static int dm816x_usb_phy_set_host(struct usb_otg *otg, struct usb_bus *host) | ||
| 63 | { | ||
| 64 | otg->host = host; | ||
| 65 | if (!host) | ||
| 66 | otg->state = OTG_STATE_UNDEFINED; | ||
| 67 | |||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int dm816x_usb_phy_set_peripheral(struct usb_otg *otg, | ||
| 72 | struct usb_gadget *gadget) | ||
| 73 | { | ||
| 74 | otg->gadget = gadget; | ||
| 75 | if (!gadget) | ||
| 76 | otg->state = OTG_STATE_UNDEFINED; | ||
| 77 | |||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static int dm816x_usb_phy_init(struct phy *x) | ||
| 82 | { | ||
| 83 | struct dm816x_usb_phy *phy = phy_get_drvdata(x); | ||
| 84 | unsigned int val; | ||
| 85 | int error; | ||
| 86 | |||
| 87 | if (clk_get_rate(phy->refclk) != 24000000) | ||
| 88 | dev_warn(phy->dev, "nonstandard phy refclk\n"); | ||
| 89 | |||
| 90 | /* Set PLL ref clock and put phys to sleep */ | ||
| 91 | error = regmap_update_bits(phy->syscon, phy->usb_ctrl, | ||
| 92 | DM816X_USB_CTRL_PHYCLKSRC | | ||
| 93 | DM816X_USB_CTRL_PHYSLEEP1 | | ||
| 94 | DM816X_USB_CTRL_PHYSLEEP0, | ||
| 95 | 0); | ||
| 96 | regmap_read(phy->syscon, phy->usb_ctrl, &val); | ||
| 97 | if ((val & 3) != 0) | ||
| 98 | dev_info(phy->dev, | ||
| 99 | "Working dm816x USB_CTRL! (0x%08x)\n", | ||
| 100 | val); | ||
| 101 | |||
| 102 | /* | ||
| 103 | * TI kernel sets these values for "symmetrical eye diagram and | ||
| 104 | * better signal quality" so let's assume somebody checked the | ||
| 105 | * values with a scope and set them here too. | ||
| 106 | */ | ||
| 107 | regmap_read(phy->syscon, phy->usbphy_ctrl, &val); | ||
| 108 | val |= DM816X_USBPHY_CTRL_TXRISETUNE | | ||
| 109 | DM816X_USBPHY_CTRL_TXVREFTUNE | | ||
| 110 | DM816X_USBPHY_CTRL_TXPREEMTUNE; | ||
| 111 | regmap_write(phy->syscon, phy->usbphy_ctrl, val); | ||
| 112 | |||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | static struct phy_ops ops = { | ||
| 117 | .init = dm816x_usb_phy_init, | ||
| 118 | .owner = THIS_MODULE, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static int dm816x_usb_phy_runtime_suspend(struct device *dev) | ||
| 122 | { | ||
| 123 | struct dm816x_usb_phy *phy = dev_get_drvdata(dev); | ||
| 124 | unsigned int mask, val; | ||
| 125 | int error = 0; | ||
| 126 | |||
| 127 | mask = BIT(phy->instance); | ||
| 128 | val = ~BIT(phy->instance); | ||
| 129 | error = regmap_update_bits(phy->syscon, phy->usb_ctrl, | ||
| 130 | mask, val); | ||
| 131 | if (error) | ||
| 132 | dev_err(phy->dev, "phy%i failed to power off\n", | ||
| 133 | phy->instance); | ||
| 134 | clk_disable(phy->refclk); | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static int dm816x_usb_phy_runtime_resume(struct device *dev) | ||
| 140 | { | ||
| 141 | struct dm816x_usb_phy *phy = dev_get_drvdata(dev); | ||
| 142 | unsigned int mask, val; | ||
| 143 | int error; | ||
| 144 | |||
| 145 | error = clk_enable(phy->refclk); | ||
| 146 | if (error) | ||
| 147 | return error; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * Note that at least dm816x rev c does not seem to do | ||
| 151 | * anything with the USB_CTRL register. But let's follow | ||
| 152 | * what the TI tree is doing in case later revisions use | ||
| 153 | * USB_CTRL. | ||
| 154 | */ | ||
| 155 | mask = BIT(phy->instance); | ||
| 156 | val = BIT(phy->instance); | ||
| 157 | error = regmap_update_bits(phy->syscon, phy->usb_ctrl, | ||
| 158 | mask, val); | ||
| 159 | if (error) { | ||
| 160 | dev_err(phy->dev, "phy%i failed to power on\n", | ||
| 161 | phy->instance); | ||
| 162 | clk_disable(phy->refclk); | ||
| 163 | return error; | ||
| 164 | } | ||
| 165 | |||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | static UNIVERSAL_DEV_PM_OPS(dm816x_usb_phy_pm_ops, | ||
| 170 | dm816x_usb_phy_runtime_suspend, | ||
| 171 | dm816x_usb_phy_runtime_resume, | ||
| 172 | NULL); | ||
| 173 | |||
| 174 | #ifdef CONFIG_OF | ||
| 175 | static const struct of_device_id dm816x_usb_phy_id_table[] = { | ||
| 176 | { | ||
| 177 | .compatible = "ti,dm8168-usb-phy", | ||
| 178 | }, | ||
| 179 | {}, | ||
| 180 | }; | ||
| 181 | MODULE_DEVICE_TABLE(of, dm816x_usb_phy_id_table); | ||
| 182 | #endif | ||
| 183 | |||
| 184 | static int dm816x_usb_phy_probe(struct platform_device *pdev) | ||
| 185 | { | ||
| 186 | struct dm816x_usb_phy *phy; | ||
| 187 | struct resource *res; | ||
| 188 | struct phy *generic_phy; | ||
| 189 | struct phy_provider *phy_provider; | ||
| 190 | struct usb_otg *otg; | ||
| 191 | const struct of_device_id *of_id; | ||
| 192 | const struct usb_phy_data *phy_data; | ||
| 193 | int error; | ||
| 194 | |||
| 195 | of_id = of_match_device(of_match_ptr(dm816x_usb_phy_id_table), | ||
| 196 | &pdev->dev); | ||
| 197 | if (!of_id) | ||
| 198 | return -EINVAL; | ||
| 199 | |||
| 200 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); | ||
| 201 | if (!phy) | ||
| 202 | return -ENOMEM; | ||
| 203 | |||
| 204 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 205 | if (!res) | ||
| 206 | return -ENOENT; | ||
| 207 | |||
| 208 | phy->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, | ||
| 209 | "syscon"); | ||
| 210 | if (IS_ERR(phy->syscon)) | ||
| 211 | return PTR_ERR(phy->syscon); | ||
| 212 | |||
| 213 | /* | ||
| 214 | * According to sprs614e.pdf, the first usb_ctrl is shared and | ||
| 215 | * the second instance for usb_ctrl is reserved.. Also the | ||
| 216 | * register bits are different from earlier TRMs. | ||
| 217 | */ | ||
| 218 | phy->usb_ctrl = 0x20; | ||
| 219 | phy->usbphy_ctrl = (res->start & 0xff) + 4; | ||
| 220 | if (phy->usbphy_ctrl == 0x2c) | ||
| 221 | phy->instance = 1; | ||
| 222 | |||
| 223 | phy_data = of_id->data; | ||
| 224 | |||
| 225 | otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); | ||
| 226 | if (!otg) | ||
| 227 | return -ENOMEM; | ||
| 228 | |||
| 229 | phy->dev = &pdev->dev; | ||
| 230 | phy->phy.dev = phy->dev; | ||
| 231 | phy->phy.label = "dm8168_usb_phy"; | ||
| 232 | phy->phy.otg = otg; | ||
| 233 | phy->phy.type = USB_PHY_TYPE_USB2; | ||
| 234 | otg->set_host = dm816x_usb_phy_set_host; | ||
| 235 | otg->set_peripheral = dm816x_usb_phy_set_peripheral; | ||
| 236 | otg->usb_phy = &phy->phy; | ||
| 237 | |||
| 238 | platform_set_drvdata(pdev, phy); | ||
| 239 | |||
| 240 | phy->refclk = devm_clk_get(phy->dev, "refclk"); | ||
| 241 | if (IS_ERR(phy->refclk)) | ||
| 242 | return PTR_ERR(phy->refclk); | ||
| 243 | error = clk_prepare(phy->refclk); | ||
| 244 | if (error) | ||
| 245 | return error; | ||
| 246 | |||
| 247 | pm_runtime_enable(phy->dev); | ||
| 248 | generic_phy = devm_phy_create(phy->dev, NULL, &ops); | ||
| 249 | if (IS_ERR(generic_phy)) | ||
| 250 | return PTR_ERR(generic_phy); | ||
| 251 | |||
| 252 | phy_set_drvdata(generic_phy, phy); | ||
| 253 | |||
| 254 | phy_provider = devm_of_phy_provider_register(phy->dev, | ||
| 255 | of_phy_simple_xlate); | ||
| 256 | if (IS_ERR(phy_provider)) | ||
| 257 | return PTR_ERR(phy_provider); | ||
| 258 | |||
| 259 | usb_add_phy_dev(&phy->phy); | ||
| 260 | |||
| 261 | return 0; | ||
| 262 | } | ||
| 263 | |||
| 264 | static int dm816x_usb_phy_remove(struct platform_device *pdev) | ||
| 265 | { | ||
| 266 | struct dm816x_usb_phy *phy = platform_get_drvdata(pdev); | ||
| 267 | |||
| 268 | usb_remove_phy(&phy->phy); | ||
| 269 | pm_runtime_disable(phy->dev); | ||
| 270 | clk_unprepare(phy->refclk); | ||
| 271 | |||
| 272 | return 0; | ||
| 273 | } | ||
| 274 | |||
| 275 | static struct platform_driver dm816x_usb_phy_driver = { | ||
| 276 | .probe = dm816x_usb_phy_probe, | ||
| 277 | .remove = dm816x_usb_phy_remove, | ||
| 278 | .driver = { | ||
| 279 | .name = "dm816x-usb-phy", | ||
| 280 | .pm = &dm816x_usb_phy_pm_ops, | ||
| 281 | .of_match_table = of_match_ptr(dm816x_usb_phy_id_table), | ||
| 282 | }, | ||
| 283 | }; | ||
| 284 | |||
| 285 | module_platform_driver(dm816x_usb_phy_driver); | ||
| 286 | |||
| 287 | MODULE_ALIAS("platform:dm816x_usb"); | ||
| 288 | MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>"); | ||
| 289 | MODULE_DESCRIPTION("dm816x usb phy driver"); | ||
| 290 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c index e2a0be750ad9..d72ef15b0d68 100644 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ b/drivers/phy/phy-exynos5-usbdrd.c | |||
| @@ -624,6 +624,13 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { | |||
| 624 | .has_common_clk_gate = true, | 624 | .has_common_clk_gate = true, |
| 625 | }; | 625 | }; |
| 626 | 626 | ||
| 627 | static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy = { | ||
| 628 | .phy_cfg = phy_cfg_exynos5, | ||
| 629 | .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, | ||
| 630 | .pmu_offset_usbdrd1_phy = EXYNOS5433_USBHOST30_PHY_CONTROL, | ||
| 631 | .has_common_clk_gate = false, | ||
| 632 | }; | ||
| 633 | |||
| 627 | static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { | 634 | static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { |
| 628 | .phy_cfg = phy_cfg_exynos5, | 635 | .phy_cfg = phy_cfg_exynos5, |
| 629 | .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, | 636 | .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, |
| @@ -638,6 +645,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { | |||
| 638 | .compatible = "samsung,exynos5420-usbdrd-phy", | 645 | .compatible = "samsung,exynos5420-usbdrd-phy", |
| 639 | .data = &exynos5420_usbdrd_phy | 646 | .data = &exynos5420_usbdrd_phy |
| 640 | }, { | 647 | }, { |
| 648 | .compatible = "samsung,exynos5433-usbdrd-phy", | ||
| 649 | .data = &exynos5433_usbdrd_phy | ||
| 650 | }, { | ||
| 641 | .compatible = "samsung,exynos7-usbdrd-phy", | 651 | .compatible = "samsung,exynos7-usbdrd-phy", |
| 642 | .data = &exynos7_usbdrd_phy | 652 | .data = &exynos7_usbdrd_phy |
| 643 | }, | 653 | }, |
diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index 933435214acc..c4cc11dcb2a2 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c | |||
| @@ -1259,10 +1259,7 @@ static int miphy28lp_probe(struct platform_device *pdev) | |||
| 1259 | } | 1259 | } |
| 1260 | 1260 | ||
| 1261 | provider = devm_of_phy_provider_register(&pdev->dev, miphy28lp_xlate); | 1261 | provider = devm_of_phy_provider_register(&pdev->dev, miphy28lp_xlate); |
| 1262 | if (IS_ERR(provider)) | 1262 | return PTR_ERR_OR_ZERO(provider); |
| 1263 | return PTR_ERR(provider); | ||
| 1264 | |||
| 1265 | return 0; | ||
| 1266 | } | 1263 | } |
| 1267 | 1264 | ||
| 1268 | static const struct of_device_id miphy28lp_of_match[] = { | 1265 | static const struct of_device_id miphy28lp_of_match[] = { |
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c index 51b459db9137..019c2d75344e 100644 --- a/drivers/phy/phy-miphy365x.c +++ b/drivers/phy/phy-miphy365x.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | #include <linux/mfd/syscon.h> | 25 | #include <linux/mfd/syscon.h> |
| 26 | #include <linux/regmap.h> | 26 | #include <linux/regmap.h> |
| 27 | 27 | ||
| 28 | #include <dt-bindings/phy/phy-miphy365x.h> | 28 | #include <dt-bindings/phy/phy.h> |
| 29 | 29 | ||
| 30 | #define HFC_TIMEOUT 100 | 30 | #define HFC_TIMEOUT 100 |
| 31 | 31 | ||
| @@ -177,7 +177,7 @@ static u8 rx_tx_spd[] = { | |||
| 177 | static int miphy365x_set_path(struct miphy365x_phy *miphy_phy, | 177 | static int miphy365x_set_path(struct miphy365x_phy *miphy_phy, |
| 178 | struct miphy365x_dev *miphy_dev) | 178 | struct miphy365x_dev *miphy_dev) |
| 179 | { | 179 | { |
| 180 | bool sata = (miphy_phy->type == MIPHY_TYPE_SATA); | 180 | bool sata = (miphy_phy->type == PHY_TYPE_SATA); |
| 181 | 181 | ||
| 182 | return regmap_update_bits(miphy_dev->regmap, | 182 | return regmap_update_bits(miphy_dev->regmap, |
| 183 | miphy_phy->ctrlreg, | 183 | miphy_phy->ctrlreg, |
| @@ -431,7 +431,7 @@ static int miphy365x_init(struct phy *phy) | |||
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | /* Initialise Miphy for PCIe or SATA */ | 433 | /* Initialise Miphy for PCIe or SATA */ |
| 434 | if (miphy_phy->type == MIPHY_TYPE_PCIE) | 434 | if (miphy_phy->type == PHY_TYPE_PCIE) |
| 435 | ret = miphy365x_init_pcie_port(miphy_phy, miphy_dev); | 435 | ret = miphy365x_init_pcie_port(miphy_phy, miphy_dev); |
| 436 | else | 436 | else |
| 437 | ret = miphy365x_init_sata_port(miphy_phy, miphy_dev); | 437 | ret = miphy365x_init_sata_port(miphy_phy, miphy_dev); |
| @@ -455,8 +455,8 @@ int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy, | |||
| 455 | return ret; | 455 | return ret; |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | if (!((!strncmp(name, "sata", 4) && type == MIPHY_TYPE_SATA) || | 458 | if (!((!strncmp(name, "sata", 4) && type == PHY_TYPE_SATA) || |
| 459 | (!strncmp(name, "pcie", 4) && type == MIPHY_TYPE_PCIE))) | 459 | (!strncmp(name, "pcie", 4) && type == PHY_TYPE_PCIE))) |
| 460 | return 0; | 460 | return 0; |
| 461 | 461 | ||
| 462 | miphy_phy->base = of_iomap(phynode, index); | 462 | miphy_phy->base = of_iomap(phynode, index); |
| @@ -499,8 +499,8 @@ static struct phy *miphy365x_xlate(struct device *dev, | |||
| 499 | 499 | ||
| 500 | miphy_phy->type = args->args[0]; | 500 | miphy_phy->type = args->args[0]; |
| 501 | 501 | ||
| 502 | if (!(miphy_phy->type == MIPHY_TYPE_SATA || | 502 | if (!(miphy_phy->type == PHY_TYPE_SATA || |
| 503 | miphy_phy->type == MIPHY_TYPE_PCIE)) { | 503 | miphy_phy->type == PHY_TYPE_PCIE)) { |
| 504 | dev_err(dev, "Unsupported device type: %d\n", miphy_phy->type); | 504 | dev_err(dev, "Unsupported device type: %d\n", miphy_phy->type); |
| 505 | return ERR_PTR(-EINVAL); | 505 | return ERR_PTR(-EINVAL); |
| 506 | } | 506 | } |
diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index 93252e053a31..e9c41b3fa0ee 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c | |||
| @@ -216,7 +216,6 @@ void omap_control_usb_set_mode(struct device *dev, | |||
| 216 | return; | 216 | return; |
| 217 | 217 | ||
| 218 | ctrl_phy = dev_get_drvdata(dev); | 218 | ctrl_phy = dev_get_drvdata(dev); |
| 219 | |||
| 220 | if (!ctrl_phy) { | 219 | if (!ctrl_phy) { |
| 221 | dev_err(dev, "Invalid control phy device\n"); | 220 | dev_err(dev, "Invalid control phy device\n"); |
| 222 | return; | 221 | return; |
| @@ -241,8 +240,6 @@ void omap_control_usb_set_mode(struct device *dev, | |||
| 241 | } | 240 | } |
| 242 | EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); | 241 | EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); |
| 243 | 242 | ||
| 244 | #ifdef CONFIG_OF | ||
| 245 | |||
| 246 | static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS; | 243 | static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS; |
| 247 | static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2; | 244 | static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2; |
| 248 | static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; | 245 | static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; |
| @@ -278,8 +275,6 @@ static const struct of_device_id omap_control_phy_id_table[] = { | |||
| 278 | {}, | 275 | {}, |
| 279 | }; | 276 | }; |
| 280 | MODULE_DEVICE_TABLE(of, omap_control_phy_id_table); | 277 | MODULE_DEVICE_TABLE(of, omap_control_phy_id_table); |
| 281 | #endif | ||
| 282 | |||
| 283 | 278 | ||
| 284 | static int omap_control_phy_probe(struct platform_device *pdev) | 279 | static int omap_control_phy_probe(struct platform_device *pdev) |
| 285 | { | 280 | { |
| @@ -287,8 +282,7 @@ static int omap_control_phy_probe(struct platform_device *pdev) | |||
| 287 | const struct of_device_id *of_id; | 282 | const struct of_device_id *of_id; |
| 288 | struct omap_control_phy *control_phy; | 283 | struct omap_control_phy *control_phy; |
| 289 | 284 | ||
| 290 | of_id = of_match_device(of_match_ptr(omap_control_phy_id_table), | 285 | of_id = of_match_device(omap_control_phy_id_table, &pdev->dev); |
| 291 | &pdev->dev); | ||
| 292 | if (!of_id) | 286 | if (!of_id) |
| 293 | return -EINVAL; | 287 | return -EINVAL; |
| 294 | 288 | ||
| @@ -344,7 +338,7 @@ static struct platform_driver omap_control_phy_driver = { | |||
| 344 | .probe = omap_control_phy_probe, | 338 | .probe = omap_control_phy_probe, |
| 345 | .driver = { | 339 | .driver = { |
| 346 | .name = "omap-control-phy", | 340 | .name = "omap-control-phy", |
| 347 | .of_match_table = of_match_ptr(omap_control_phy_id_table), | 341 | .of_match_table = omap_control_phy_id_table, |
| 348 | }, | 342 | }, |
| 349 | }; | 343 | }; |
| 350 | 344 | ||
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 4757e765696a..183ef4368101 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c | |||
| @@ -144,7 +144,6 @@ static struct phy_ops ops = { | |||
| 144 | .owner = THIS_MODULE, | 144 | .owner = THIS_MODULE, |
| 145 | }; | 145 | }; |
| 146 | 146 | ||
| 147 | #ifdef CONFIG_OF | ||
| 148 | static const struct usb_phy_data omap_usb2_data = { | 147 | static const struct usb_phy_data omap_usb2_data = { |
| 149 | .label = "omap_usb2", | 148 | .label = "omap_usb2", |
| 150 | .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS, | 149 | .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS, |
| @@ -185,7 +184,6 @@ static const struct of_device_id omap_usb2_id_table[] = { | |||
| 185 | {}, | 184 | {}, |
| 186 | }; | 185 | }; |
| 187 | MODULE_DEVICE_TABLE(of, omap_usb2_id_table); | 186 | MODULE_DEVICE_TABLE(of, omap_usb2_id_table); |
| 188 | #endif | ||
| 189 | 187 | ||
| 190 | static int omap_usb2_probe(struct platform_device *pdev) | 188 | static int omap_usb2_probe(struct platform_device *pdev) |
| 191 | { | 189 | { |
| @@ -200,7 +198,7 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
| 200 | const struct of_device_id *of_id; | 198 | const struct of_device_id *of_id; |
| 201 | struct usb_phy_data *phy_data; | 199 | struct usb_phy_data *phy_data; |
| 202 | 200 | ||
| 203 | of_id = of_match_device(of_match_ptr(omap_usb2_id_table), &pdev->dev); | 201 | of_id = of_match_device(omap_usb2_id_table, &pdev->dev); |
| 204 | 202 | ||
| 205 | if (!of_id) | 203 | if (!of_id) |
| 206 | return -EINVAL; | 204 | return -EINVAL; |
| @@ -378,7 +376,7 @@ static struct platform_driver omap_usb2_driver = { | |||
| 378 | .driver = { | 376 | .driver = { |
| 379 | .name = "omap-usb2", | 377 | .name = "omap-usb2", |
| 380 | .pm = DEV_PM_OPS, | 378 | .pm = DEV_PM_OPS, |
| 381 | .of_match_table = of_match_ptr(omap_usb2_id_table), | 379 | .of_match_table = omap_usb2_id_table, |
| 382 | }, | 380 | }, |
| 383 | }; | 381 | }; |
| 384 | 382 | ||
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c index 44ee983d57fe..c4199e605ce2 100644 --- a/drivers/phy/phy-qcom-ufs.c +++ b/drivers/phy/phy-qcom-ufs.c | |||
| @@ -73,6 +73,7 @@ int ufs_qcom_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, | |||
| 73 | out: | 73 | out: |
| 74 | return ret; | 74 | return ret; |
| 75 | } | 75 | } |
| 76 | EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate); | ||
| 76 | 77 | ||
| 77 | struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, | 78 | struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, |
| 78 | struct ufs_qcom_phy *common_cfg, | 79 | struct ufs_qcom_phy *common_cfg, |
| @@ -101,6 +102,7 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, | |||
| 101 | if (IS_ERR(generic_phy)) { | 102 | if (IS_ERR(generic_phy)) { |
| 102 | err = PTR_ERR(generic_phy); | 103 | err = PTR_ERR(generic_phy); |
| 103 | dev_err(dev, "%s: failed to create phy %d\n", __func__, err); | 104 | dev_err(dev, "%s: failed to create phy %d\n", __func__, err); |
| 105 | generic_phy = NULL; | ||
| 104 | goto out; | 106 | goto out; |
| 105 | } | 107 | } |
| 106 | 108 | ||
| @@ -110,6 +112,7 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, | |||
| 110 | out: | 112 | out: |
| 111 | return generic_phy; | 113 | return generic_phy; |
| 112 | } | 114 | } |
| 115 | EXPORT_SYMBOL_GPL(ufs_qcom_phy_generic_probe); | ||
| 113 | 116 | ||
| 114 | /* | 117 | /* |
| 115 | * This assumes the embedded phy structure inside generic_phy is of type | 118 | * This assumes the embedded phy structure inside generic_phy is of type |
| @@ -121,6 +124,7 @@ struct ufs_qcom_phy *get_ufs_qcom_phy(struct phy *generic_phy) | |||
| 121 | { | 124 | { |
| 122 | return (struct ufs_qcom_phy *)phy_get_drvdata(generic_phy); | 125 | return (struct ufs_qcom_phy *)phy_get_drvdata(generic_phy); |
| 123 | } | 126 | } |
| 127 | EXPORT_SYMBOL_GPL(get_ufs_qcom_phy); | ||
| 124 | 128 | ||
| 125 | static | 129 | static |
| 126 | int ufs_qcom_phy_base_init(struct platform_device *pdev, | 130 | int ufs_qcom_phy_base_init(struct platform_device *pdev, |
| @@ -131,40 +135,23 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev, | |||
| 131 | int err = 0; | 135 | int err = 0; |
| 132 | 136 | ||
| 133 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem"); | 137 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem"); |
| 134 | if (!res) { | ||
| 135 | dev_err(dev, "%s: phy_mem resource not found\n", __func__); | ||
| 136 | err = -ENOMEM; | ||
| 137 | goto out; | ||
| 138 | } | ||
| 139 | |||
| 140 | phy_common->mmio = devm_ioremap_resource(dev, res); | 138 | phy_common->mmio = devm_ioremap_resource(dev, res); |
| 141 | if (IS_ERR((void const *)phy_common->mmio)) { | 139 | if (IS_ERR((void const *)phy_common->mmio)) { |
| 142 | err = PTR_ERR((void const *)phy_common->mmio); | 140 | err = PTR_ERR((void const *)phy_common->mmio); |
| 143 | phy_common->mmio = NULL; | 141 | phy_common->mmio = NULL; |
| 144 | dev_err(dev, "%s: ioremap for phy_mem resource failed %d\n", | 142 | dev_err(dev, "%s: ioremap for phy_mem resource failed %d\n", |
| 145 | __func__, err); | 143 | __func__, err); |
| 146 | goto out; | 144 | return err; |
| 147 | } | 145 | } |
| 148 | 146 | ||
| 149 | /* "dev_ref_clk_ctrl_mem" is optional resource */ | 147 | /* "dev_ref_clk_ctrl_mem" is optional resource */ |
| 150 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 148 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
| 151 | "dev_ref_clk_ctrl_mem"); | 149 | "dev_ref_clk_ctrl_mem"); |
| 152 | if (!res) { | ||
| 153 | dev_dbg(dev, "%s: dev_ref_clk_ctrl_mem resource not found\n", | ||
| 154 | __func__); | ||
| 155 | goto out; | ||
| 156 | } | ||
| 157 | |||
| 158 | phy_common->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res); | 150 | phy_common->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res); |
| 159 | if (IS_ERR((void const *)phy_common->dev_ref_clk_ctrl_mmio)) { | 151 | if (IS_ERR((void const *)phy_common->dev_ref_clk_ctrl_mmio)) |
| 160 | err = PTR_ERR((void const *)phy_common->dev_ref_clk_ctrl_mmio); | ||
| 161 | phy_common->dev_ref_clk_ctrl_mmio = NULL; | 152 | phy_common->dev_ref_clk_ctrl_mmio = NULL; |
| 162 | dev_err(dev, "%s: ioremap for dev_ref_clk_ctrl_mem resource failed %d\n", | ||
| 163 | __func__, err); | ||
| 164 | } | ||
| 165 | 153 | ||
| 166 | out: | 154 | return 0; |
| 167 | return err; | ||
| 168 | } | 155 | } |
| 169 | 156 | ||
| 170 | static int __ufs_qcom_phy_clk_get(struct phy *phy, | 157 | static int __ufs_qcom_phy_clk_get(struct phy *phy, |
| @@ -228,6 +215,7 @@ ufs_qcom_phy_init_clks(struct phy *generic_phy, | |||
| 228 | out: | 215 | out: |
| 229 | return err; | 216 | return err; |
| 230 | } | 217 | } |
| 218 | EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_clks); | ||
| 231 | 219 | ||
| 232 | int | 220 | int |
| 233 | ufs_qcom_phy_init_vregulators(struct phy *generic_phy, | 221 | ufs_qcom_phy_init_vregulators(struct phy *generic_phy, |
| @@ -252,6 +240,7 @@ ufs_qcom_phy_init_vregulators(struct phy *generic_phy, | |||
| 252 | out: | 240 | out: |
| 253 | return err; | 241 | return err; |
| 254 | } | 242 | } |
| 243 | EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_vregulators); | ||
| 255 | 244 | ||
| 256 | static int __ufs_qcom_phy_init_vreg(struct phy *phy, | 245 | static int __ufs_qcom_phy_init_vreg(struct phy *phy, |
| 257 | struct ufs_qcom_phy_vreg *vreg, const char *name, bool optional) | 246 | struct ufs_qcom_phy_vreg *vreg, const char *name, bool optional) |
| @@ -647,6 +636,7 @@ int ufs_qcom_phy_remove(struct phy *generic_phy, | |||
| 647 | 636 | ||
| 648 | return 0; | 637 | return 0; |
| 649 | } | 638 | } |
| 639 | EXPORT_SYMBOL_GPL(ufs_qcom_phy_remove); | ||
| 650 | 640 | ||
| 651 | int ufs_qcom_phy_exit(struct phy *generic_phy) | 641 | int ufs_qcom_phy_exit(struct phy *generic_phy) |
| 652 | { | 642 | { |
| @@ -657,6 +647,7 @@ int ufs_qcom_phy_exit(struct phy *generic_phy) | |||
| 657 | 647 | ||
| 658 | return 0; | 648 | return 0; |
| 659 | } | 649 | } |
| 650 | EXPORT_SYMBOL_GPL(ufs_qcom_phy_exit); | ||
| 660 | 651 | ||
| 661 | int ufs_qcom_phy_is_pcs_ready(struct phy *generic_phy) | 652 | int ufs_qcom_phy_is_pcs_ready(struct phy *generic_phy) |
| 662 | { | 653 | { |
| @@ -725,6 +716,7 @@ out_disable_phy: | |||
| 725 | out: | 716 | out: |
| 726 | return err; | 717 | return err; |
| 727 | } | 718 | } |
| 719 | EXPORT_SYMBOL_GPL(ufs_qcom_phy_power_on); | ||
| 728 | 720 | ||
| 729 | int ufs_qcom_phy_power_off(struct phy *generic_phy) | 721 | int ufs_qcom_phy_power_off(struct phy *generic_phy) |
| 730 | { | 722 | { |
| @@ -743,3 +735,4 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy) | |||
| 743 | 735 | ||
| 744 | return 0; | 736 | return 0; |
| 745 | } | 737 | } |
| 738 | EXPORT_SYMBOL_GPL(ufs_qcom_phy_power_off); | ||
diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c index 4a12f66b7fb5..55b6994932e3 100644 --- a/drivers/phy/phy-samsung-usb2.c +++ b/drivers/phy/phy-samsung-usb2.c | |||
| @@ -37,10 +37,14 @@ static int samsung_usb2_phy_power_on(struct phy *phy) | |||
| 37 | spin_lock(&drv->lock); | 37 | spin_lock(&drv->lock); |
| 38 | ret = inst->cfg->power_on(inst); | 38 | ret = inst->cfg->power_on(inst); |
| 39 | spin_unlock(&drv->lock); | 39 | spin_unlock(&drv->lock); |
| 40 | if (ret) | ||
| 41 | goto err_power_on; | ||
| 40 | } | 42 | } |
| 41 | 43 | ||
| 42 | return 0; | 44 | return 0; |
| 43 | 45 | ||
| 46 | err_power_on: | ||
| 47 | clk_disable_unprepare(drv->ref_clk); | ||
| 44 | err_instance_clk: | 48 | err_instance_clk: |
| 45 | clk_disable_unprepare(drv->clk); | 49 | clk_disable_unprepare(drv->clk); |
| 46 | err_main_clk: | 50 | err_main_clk: |
| @@ -51,7 +55,7 @@ static int samsung_usb2_phy_power_off(struct phy *phy) | |||
| 51 | { | 55 | { |
| 52 | struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); | 56 | struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); |
| 53 | struct samsung_usb2_phy_driver *drv = inst->drv; | 57 | struct samsung_usb2_phy_driver *drv = inst->drv; |
| 54 | int ret = 0; | 58 | int ret; |
| 55 | 59 | ||
| 56 | dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n", | 60 | dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n", |
| 57 | inst->cfg->label); | 61 | inst->cfg->label); |
| @@ -59,10 +63,12 @@ static int samsung_usb2_phy_power_off(struct phy *phy) | |||
| 59 | spin_lock(&drv->lock); | 63 | spin_lock(&drv->lock); |
| 60 | ret = inst->cfg->power_off(inst); | 64 | ret = inst->cfg->power_off(inst); |
| 61 | spin_unlock(&drv->lock); | 65 | spin_unlock(&drv->lock); |
| 66 | if (ret) | ||
| 67 | return ret; | ||
| 62 | } | 68 | } |
| 63 | clk_disable_unprepare(drv->ref_clk); | 69 | clk_disable_unprepare(drv->ref_clk); |
| 64 | clk_disable_unprepare(drv->clk); | 70 | clk_disable_unprepare(drv->clk); |
| 65 | return ret; | 71 | return 0; |
| 66 | } | 72 | } |
| 67 | 73 | ||
| 68 | static struct phy_ops samsung_usb2_phy_ops = { | 74 | static struct phy_ops samsung_usb2_phy_ops = { |
diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c index 9f47fae7eecb..65ae640cfbd1 100644 --- a/drivers/phy/phy-spear1310-miphy.c +++ b/drivers/phy/phy-spear1310-miphy.c | |||
| @@ -192,14 +192,14 @@ static struct phy *spear1310_miphy_xlate(struct device *dev, | |||
| 192 | 192 | ||
| 193 | if (args->args_count < 1) { | 193 | if (args->args_count < 1) { |
| 194 | dev_err(dev, "DT did not pass correct no of args\n"); | 194 | dev_err(dev, "DT did not pass correct no of args\n"); |
| 195 | return NULL; | 195 | return ERR_PTR(-ENODEV); |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | priv->mode = args->args[0]; | 198 | priv->mode = args->args[0]; |
| 199 | 199 | ||
| 200 | if (priv->mode != SATA && priv->mode != PCIE) { | 200 | if (priv->mode != SATA && priv->mode != PCIE) { |
| 201 | dev_err(dev, "DT did not pass correct phy mode\n"); | 201 | dev_err(dev, "DT did not pass correct phy mode\n"); |
| 202 | return NULL; | 202 | return ERR_PTR(-ENODEV); |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | return priv->phy; | 205 | return priv->phy; |
diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c index e42bc200275f..1a00c2817f34 100644 --- a/drivers/phy/phy-spear1340-miphy.c +++ b/drivers/phy/phy-spear1340-miphy.c | |||
| @@ -229,14 +229,14 @@ static struct phy *spear1340_miphy_xlate(struct device *dev, | |||
| 229 | 229 | ||
| 230 | if (args->args_count < 1) { | 230 | if (args->args_count < 1) { |
| 231 | dev_err(dev, "DT did not pass correct no of args\n"); | 231 | dev_err(dev, "DT did not pass correct no of args\n"); |
| 232 | return NULL; | 232 | return ERR_PTR(-ENODEV); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | priv->mode = args->args[0]; | 235 | priv->mode = args->args[0]; |
| 236 | 236 | ||
| 237 | if (priv->mode != SATA && priv->mode != PCIE) { | 237 | if (priv->mode != SATA && priv->mode != PCIE) { |
| 238 | dev_err(dev, "DT did not pass correct phy mode\n"); | 238 | dev_err(dev, "DT did not pass correct phy mode\n"); |
| 239 | return NULL; | 239 | return ERR_PTR(-ENODEV); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | return priv->phy; | 242 | return priv->phy; |
diff --git a/drivers/phy/phy-stih41x-usb.c b/drivers/phy/phy-stih41x-usb.c index a603801293ff..c093b472b57d 100644 --- a/drivers/phy/phy-stih41x-usb.c +++ b/drivers/phy/phy-stih41x-usb.c | |||
| @@ -87,8 +87,12 @@ static int stih41x_usb_phy_power_on(struct phy *phy) | |||
| 87 | return ret; | 87 | return ret; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | return regmap_update_bits(phy_dev->regmap, phy_dev->cfg->syscfg, | 90 | ret = regmap_update_bits(phy_dev->regmap, phy_dev->cfg->syscfg, |
| 91 | phy_dev->cfg->oscok, phy_dev->cfg->oscok); | 91 | phy_dev->cfg->oscok, phy_dev->cfg->oscok); |
| 92 | if (ret) | ||
| 93 | clk_disable_unprepare(phy_dev->clk); | ||
| 94 | |||
| 95 | return ret; | ||
| 92 | } | 96 | } |
| 93 | 97 | ||
| 94 | static int stih41x_usb_phy_power_off(struct phy *phy) | 98 | static int stih41x_usb_phy_power_off(struct phy *phy) |
diff --git a/drivers/phy/phy-sun9i-usb.c b/drivers/phy/phy-sun9i-usb.c new file mode 100644 index 000000000000..0095914a662c --- /dev/null +++ b/drivers/phy/phy-sun9i-usb.c | |||
| @@ -0,0 +1,202 @@ | |||
| 1 | /* | ||
| 2 | * Allwinner sun9i USB phy driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014-2015 Chen-Yu Tsai <wens@csie.org> | ||
| 5 | * | ||
| 6 | * Based on phy-sun4i-usb.c from | ||
| 7 | * Hans de Goede <hdegoede@redhat.com> | ||
| 8 | * | ||
| 9 | * and code from | ||
| 10 | * Allwinner Technology Co., Ltd. <www.allwinnertech.com> | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation; either version 2 of the License, or | ||
| 15 | * (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/clk.h> | ||
| 24 | #include <linux/err.h> | ||
| 25 | #include <linux/io.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/phy/phy.h> | ||
| 28 | #include <linux/usb/of.h> | ||
| 29 | #include <linux/platform_device.h> | ||
| 30 | #include <linux/reset.h> | ||
| 31 | |||
| 32 | #define SUNXI_AHB_INCR16_BURST_EN BIT(11) | ||
| 33 | #define SUNXI_AHB_INCR8_BURST_EN BIT(10) | ||
| 34 | #define SUNXI_AHB_INCR4_BURST_EN BIT(9) | ||
| 35 | #define SUNXI_AHB_INCRX_ALIGN_EN BIT(8) | ||
| 36 | #define SUNXI_ULPI_BYPASS_EN BIT(0) | ||
| 37 | |||
| 38 | /* usb1 HSIC specific bits */ | ||
| 39 | #define SUNXI_EHCI_HS_FORCE BIT(20) | ||
| 40 | #define SUNXI_HSIC_CONNECT_DET BIT(17) | ||
| 41 | #define SUNXI_HSIC_CONNECT_INT BIT(16) | ||
| 42 | #define SUNXI_HSIC BIT(1) | ||
| 43 | |||
| 44 | struct sun9i_usb_phy { | ||
| 45 | struct phy *phy; | ||
| 46 | void __iomem *pmu; | ||
| 47 | struct reset_control *reset; | ||
| 48 | struct clk *clk; | ||
| 49 | struct clk *hsic_clk; | ||
| 50 | enum usb_phy_interface type; | ||
| 51 | }; | ||
| 52 | |||
| 53 | static void sun9i_usb_phy_passby(struct sun9i_usb_phy *phy, int enable) | ||
| 54 | { | ||
| 55 | u32 bits, reg_value; | ||
| 56 | |||
| 57 | bits = SUNXI_AHB_INCR16_BURST_EN | SUNXI_AHB_INCR8_BURST_EN | | ||
| 58 | SUNXI_AHB_INCR4_BURST_EN | SUNXI_AHB_INCRX_ALIGN_EN | | ||
| 59 | SUNXI_ULPI_BYPASS_EN; | ||
| 60 | |||
| 61 | if (phy->type == USBPHY_INTERFACE_MODE_HSIC) | ||
| 62 | bits |= SUNXI_HSIC | SUNXI_EHCI_HS_FORCE | | ||
| 63 | SUNXI_HSIC_CONNECT_DET | SUNXI_HSIC_CONNECT_INT; | ||
| 64 | |||
| 65 | reg_value = readl(phy->pmu); | ||
| 66 | |||
| 67 | if (enable) | ||
| 68 | reg_value |= bits; | ||
| 69 | else | ||
| 70 | reg_value &= ~bits; | ||
| 71 | |||
| 72 | writel(reg_value, phy->pmu); | ||
| 73 | } | ||
| 74 | |||
| 75 | static int sun9i_usb_phy_init(struct phy *_phy) | ||
| 76 | { | ||
| 77 | struct sun9i_usb_phy *phy = phy_get_drvdata(_phy); | ||
| 78 | int ret; | ||
| 79 | |||
| 80 | ret = clk_prepare_enable(phy->clk); | ||
| 81 | if (ret) | ||
| 82 | goto err_clk; | ||
| 83 | |||
| 84 | ret = clk_prepare_enable(phy->hsic_clk); | ||
| 85 | if (ret) | ||
| 86 | goto err_hsic_clk; | ||
| 87 | |||
| 88 | ret = reset_control_deassert(phy->reset); | ||
| 89 | if (ret) | ||
| 90 | goto err_reset; | ||
| 91 | |||
| 92 | sun9i_usb_phy_passby(phy, 1); | ||
| 93 | return 0; | ||
| 94 | |||
| 95 | err_reset: | ||
| 96 | clk_disable_unprepare(phy->hsic_clk); | ||
| 97 | |||
| 98 | err_hsic_clk: | ||
| 99 | clk_disable_unprepare(phy->clk); | ||
| 100 | |||
| 101 | err_clk: | ||
| 102 | return ret; | ||
| 103 | } | ||
| 104 | |||
| 105 | static int sun9i_usb_phy_exit(struct phy *_phy) | ||
| 106 | { | ||
| 107 | struct sun9i_usb_phy *phy = phy_get_drvdata(_phy); | ||
| 108 | |||
| 109 | sun9i_usb_phy_passby(phy, 0); | ||
| 110 | reset_control_assert(phy->reset); | ||
| 111 | clk_disable_unprepare(phy->hsic_clk); | ||
| 112 | clk_disable_unprepare(phy->clk); | ||
| 113 | |||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | static struct phy_ops sun9i_usb_phy_ops = { | ||
| 118 | .init = sun9i_usb_phy_init, | ||
| 119 | .exit = sun9i_usb_phy_exit, | ||
| 120 | .owner = THIS_MODULE, | ||
| 121 | }; | ||
| 122 | |||
| 123 | static int sun9i_usb_phy_probe(struct platform_device *pdev) | ||
| 124 | { | ||
| 125 | struct sun9i_usb_phy *phy; | ||
| 126 | struct device *dev = &pdev->dev; | ||
| 127 | struct device_node *np = dev->of_node; | ||
| 128 | struct phy_provider *phy_provider; | ||
| 129 | struct resource *res; | ||
| 130 | |||
| 131 | phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); | ||
| 132 | if (!phy) | ||
| 133 | return -ENOMEM; | ||
| 134 | |||
| 135 | phy->type = of_usb_get_phy_mode(np); | ||
| 136 | if (phy->type == USBPHY_INTERFACE_MODE_HSIC) { | ||
| 137 | phy->clk = devm_clk_get(dev, "hsic_480M"); | ||
| 138 | if (IS_ERR(phy->clk)) { | ||
| 139 | dev_err(dev, "failed to get hsic_480M clock\n"); | ||
| 140 | return PTR_ERR(phy->clk); | ||
| 141 | } | ||
| 142 | |||
| 143 | phy->hsic_clk = devm_clk_get(dev, "hsic_12M"); | ||
| 144 | if (IS_ERR(phy->clk)) { | ||
| 145 | dev_err(dev, "failed to get hsic_12M clock\n"); | ||
| 146 | return PTR_ERR(phy->clk); | ||
| 147 | } | ||
| 148 | |||
| 149 | phy->reset = devm_reset_control_get(dev, "hsic"); | ||
| 150 | if (IS_ERR(phy->reset)) { | ||
| 151 | dev_err(dev, "failed to get reset control\n"); | ||
| 152 | return PTR_ERR(phy->reset); | ||
| 153 | } | ||
| 154 | } else { | ||
| 155 | phy->clk = devm_clk_get(dev, "phy"); | ||
| 156 | if (IS_ERR(phy->clk)) { | ||
| 157 | dev_err(dev, "failed to get phy clock\n"); | ||
| 158 | return PTR_ERR(phy->clk); | ||
| 159 | } | ||
| 160 | |||
| 161 | phy->reset = devm_reset_control_get(dev, "phy"); | ||
| 162 | if (IS_ERR(phy->reset)) { | ||
| 163 | dev_err(dev, "failed to get reset control\n"); | ||
| 164 | return PTR_ERR(phy->reset); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 169 | phy->pmu = devm_ioremap_resource(dev, res); | ||
| 170 | if (IS_ERR(phy->pmu)) | ||
| 171 | return PTR_ERR(phy->pmu); | ||
| 172 | |||
| 173 | phy->phy = devm_phy_create(dev, NULL, &sun9i_usb_phy_ops); | ||
| 174 | if (IS_ERR(phy->phy)) { | ||
| 175 | dev_err(dev, "failed to create PHY\n"); | ||
| 176 | return PTR_ERR(phy->phy); | ||
| 177 | } | ||
| 178 | |||
| 179 | phy_set_drvdata(phy->phy, phy); | ||
| 180 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
| 181 | |||
| 182 | return PTR_ERR_OR_ZERO(phy_provider); | ||
| 183 | } | ||
| 184 | |||
| 185 | static const struct of_device_id sun9i_usb_phy_of_match[] = { | ||
| 186 | { .compatible = "allwinner,sun9i-a80-usb-phy" }, | ||
| 187 | { }, | ||
| 188 | }; | ||
| 189 | MODULE_DEVICE_TABLE(of, sun9i_usb_phy_of_match); | ||
| 190 | |||
| 191 | static struct platform_driver sun9i_usb_phy_driver = { | ||
| 192 | .probe = sun9i_usb_phy_probe, | ||
| 193 | .driver = { | ||
| 194 | .of_match_table = sun9i_usb_phy_of_match, | ||
| 195 | .name = "sun9i-usb-phy", | ||
| 196 | } | ||
| 197 | }; | ||
| 198 | module_platform_driver(sun9i_usb_phy_driver); | ||
| 199 | |||
| 200 | MODULE_DESCRIPTION("Allwinner sun9i USB phy driver"); | ||
| 201 | MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); | ||
| 202 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 2ba610b72ca2..53f295c1bab1 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c | |||
| @@ -287,9 +287,7 @@ static struct phy_ops ops = { | |||
| 287 | .owner = THIS_MODULE, | 287 | .owner = THIS_MODULE, |
| 288 | }; | 288 | }; |
| 289 | 289 | ||
| 290 | #ifdef CONFIG_OF | ||
| 291 | static const struct of_device_id ti_pipe3_id_table[]; | 290 | static const struct of_device_id ti_pipe3_id_table[]; |
| 292 | #endif | ||
| 293 | 291 | ||
| 294 | static int ti_pipe3_probe(struct platform_device *pdev) | 292 | static int ti_pipe3_probe(struct platform_device *pdev) |
| 295 | { | 293 | { |
| @@ -311,8 +309,7 @@ static int ti_pipe3_probe(struct platform_device *pdev) | |||
| 311 | spin_lock_init(&phy->lock); | 309 | spin_lock_init(&phy->lock); |
| 312 | 310 | ||
| 313 | if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { | 311 | if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { |
| 314 | match = of_match_device(of_match_ptr(ti_pipe3_id_table), | 312 | match = of_match_device(ti_pipe3_id_table, &pdev->dev); |
| 315 | &pdev->dev); | ||
| 316 | if (!match) | 313 | if (!match) |
| 317 | return -EINVAL; | 314 | return -EINVAL; |
| 318 | 315 | ||
| @@ -570,7 +567,6 @@ static const struct dev_pm_ops ti_pipe3_pm_ops = { | |||
| 570 | SET_SYSTEM_SLEEP_PM_OPS(ti_pipe3_suspend, ti_pipe3_resume) | 567 | SET_SYSTEM_SLEEP_PM_OPS(ti_pipe3_suspend, ti_pipe3_resume) |
| 571 | }; | 568 | }; |
| 572 | 569 | ||
| 573 | #ifdef CONFIG_OF | ||
| 574 | static const struct of_device_id ti_pipe3_id_table[] = { | 570 | static const struct of_device_id ti_pipe3_id_table[] = { |
| 575 | { | 571 | { |
| 576 | .compatible = "ti,phy-usb3", | 572 | .compatible = "ti,phy-usb3", |
| @@ -590,7 +586,6 @@ static const struct of_device_id ti_pipe3_id_table[] = { | |||
| 590 | {} | 586 | {} |
| 591 | }; | 587 | }; |
| 592 | MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); | 588 | MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); |
| 593 | #endif | ||
| 594 | 589 | ||
| 595 | static struct platform_driver ti_pipe3_driver = { | 590 | static struct platform_driver ti_pipe3_driver = { |
| 596 | .probe = ti_pipe3_probe, | 591 | .probe = ti_pipe3_probe, |
| @@ -598,7 +593,7 @@ static struct platform_driver ti_pipe3_driver = { | |||
| 598 | .driver = { | 593 | .driver = { |
| 599 | .name = "ti-pipe3", | 594 | .name = "ti-pipe3", |
| 600 | .pm = &ti_pipe3_pm_ops, | 595 | .pm = &ti_pipe3_pm_ops, |
| 601 | .of_match_table = of_match_ptr(ti_pipe3_id_table), | 596 | .of_match_table = ti_pipe3_id_table, |
| 602 | }, | 597 | }, |
| 603 | }; | 598 | }; |
| 604 | 599 | ||
diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c index 2263cd010032..385362e5b2f6 100644 --- a/drivers/phy/phy-xgene.c +++ b/drivers/phy/phy-xgene.c | |||
| @@ -1657,7 +1657,6 @@ static int xgene_phy_probe(struct platform_device *pdev) | |||
| 1657 | struct phy_provider *phy_provider; | 1657 | struct phy_provider *phy_provider; |
| 1658 | struct xgene_phy_ctx *ctx; | 1658 | struct xgene_phy_ctx *ctx; |
| 1659 | struct resource *res; | 1659 | struct resource *res; |
| 1660 | int rc = 0; | ||
| 1661 | u32 default_spd[] = DEFAULT_SATA_SPD_SEL; | 1660 | u32 default_spd[] = DEFAULT_SATA_SPD_SEL; |
| 1662 | u32 default_txboost_gain[] = DEFAULT_SATA_TXBOOST_GAIN; | 1661 | u32 default_txboost_gain[] = DEFAULT_SATA_TXBOOST_GAIN; |
| 1663 | u32 default_txeye_direction[] = DEFAULT_SATA_TXEYEDIRECTION; | 1662 | u32 default_txeye_direction[] = DEFAULT_SATA_TXEYEDIRECTION; |
| @@ -1676,10 +1675,8 @@ static int xgene_phy_probe(struct platform_device *pdev) | |||
| 1676 | 1675 | ||
| 1677 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1676 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1678 | ctx->sds_base = devm_ioremap_resource(&pdev->dev, res); | 1677 | ctx->sds_base = devm_ioremap_resource(&pdev->dev, res); |
| 1679 | if (IS_ERR(ctx->sds_base)) { | 1678 | if (IS_ERR(ctx->sds_base)) |
| 1680 | rc = PTR_ERR(ctx->sds_base); | 1679 | return PTR_ERR(ctx->sds_base); |
| 1681 | goto error; | ||
| 1682 | } | ||
| 1683 | 1680 | ||
| 1684 | /* Retrieve optional clock */ | 1681 | /* Retrieve optional clock */ |
| 1685 | ctx->clk = clk_get(&pdev->dev, NULL); | 1682 | ctx->clk = clk_get(&pdev->dev, NULL); |
| @@ -1709,22 +1706,12 @@ static int xgene_phy_probe(struct platform_device *pdev) | |||
| 1709 | ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops); | 1706 | ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops); |
| 1710 | if (IS_ERR(ctx->phy)) { | 1707 | if (IS_ERR(ctx->phy)) { |
| 1711 | dev_dbg(&pdev->dev, "Failed to create PHY\n"); | 1708 | dev_dbg(&pdev->dev, "Failed to create PHY\n"); |
| 1712 | rc = PTR_ERR(ctx->phy); | 1709 | return PTR_ERR(ctx->phy); |
| 1713 | goto error; | ||
| 1714 | } | 1710 | } |
| 1715 | phy_set_drvdata(ctx->phy, ctx); | 1711 | phy_set_drvdata(ctx->phy, ctx); |
| 1716 | 1712 | ||
| 1717 | phy_provider = devm_of_phy_provider_register(ctx->dev, | 1713 | phy_provider = devm_of_phy_provider_register(ctx->dev, xgene_phy_xlate); |
| 1718 | xgene_phy_xlate); | 1714 | return PTR_ERR_OR_ZERO(phy_provider); |
| 1719 | if (IS_ERR(phy_provider)) { | ||
| 1720 | rc = PTR_ERR(phy_provider); | ||
| 1721 | goto error; | ||
| 1722 | } | ||
| 1723 | |||
| 1724 | return 0; | ||
| 1725 | |||
| 1726 | error: | ||
| 1727 | return rc; | ||
| 1728 | } | 1715 | } |
| 1729 | 1716 | ||
| 1730 | static const struct of_device_id xgene_phy_of_match[] = { | 1717 | static const struct of_device_id xgene_phy_of_match[] = { |
diff --git a/include/dt-bindings/phy/phy-miphy365x.h b/include/dt-bindings/phy/phy-miphy365x.h deleted file mode 100644 index 8ef8aba6edd6..000000000000 --- a/include/dt-bindings/phy/phy-miphy365x.h +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This header provides constants for the phy framework | ||
| 3 | * based on the STMicroelectronics MiPHY365x. | ||
| 4 | * | ||
| 5 | * Author: Lee Jones <lee.jones@linaro.org> | ||
| 6 | */ | ||
| 7 | #ifndef _DT_BINDINGS_PHY_MIPHY | ||
| 8 | #define _DT_BINDINGS_PHY_MIPHY | ||
| 9 | |||
| 10 | #define MIPHY_TYPE_SATA 1 | ||
| 11 | #define MIPHY_TYPE_PCIE 2 | ||
| 12 | #define MIPHY_TYPE_USB 3 | ||
| 13 | |||
| 14 | #endif /* _DT_BINDINGS_PHY_MIPHY */ | ||
diff --git a/include/linux/mfd/syscon/exynos5-pmu.h b/include/linux/mfd/syscon/exynos5-pmu.h index 00ef24bf6ede..9352adc95de6 100644 --- a/include/linux/mfd/syscon/exynos5-pmu.h +++ b/include/linux/mfd/syscon/exynos5-pmu.h | |||
| @@ -36,6 +36,9 @@ | |||
| 36 | #define EXYNOS5420_MTCADC_PHY_CONTROL (0x724) | 36 | #define EXYNOS5420_MTCADC_PHY_CONTROL (0x724) |
| 37 | #define EXYNOS5420_DPTX_PHY_CONTROL (0x728) | 37 | #define EXYNOS5420_DPTX_PHY_CONTROL (0x728) |
| 38 | 38 | ||
| 39 | /* Exynos5433 specific register definitions */ | ||
| 40 | #define EXYNOS5433_USBHOST30_PHY_CONTROL (0x728) | ||
| 41 | |||
| 39 | #define EXYNOS5_PHY_ENABLE BIT(0) | 42 | #define EXYNOS5_PHY_ENABLE BIT(0) |
| 40 | 43 | ||
| 41 | #define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) | 44 | #define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) |
