.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | | - * Samsung EXYNOS5 SoC series USB DRD PHY driver |
---|
| 3 | + * Samsung Exynos5 SoC series USB DRD PHY driver |
---|
3 | 4 | * |
---|
4 | 5 | * Phy provider for USB 3.0 DRD controller on Exynos5 SoC series |
---|
5 | 6 | * |
---|
6 | 7 | * Copyright (C) 2014 Samsung Electronics Co., Ltd. |
---|
7 | 8 | * Author: Vivek Gautam <gautam.vivek@samsung.com> |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License version 2 as |
---|
11 | | - * published by the Free Software Foundation. |
---|
12 | 9 | */ |
---|
13 | 10 | |
---|
14 | 11 | #include <linux/clk.h> |
---|
.. | .. |
---|
19 | 16 | #include <linux/of.h> |
---|
20 | 17 | #include <linux/of_address.h> |
---|
21 | 18 | #include <linux/of_device.h> |
---|
| 19 | +#include <linux/iopoll.h> |
---|
22 | 20 | #include <linux/phy/phy.h> |
---|
23 | 21 | #include <linux/platform_device.h> |
---|
24 | 22 | #include <linux/mutex.h> |
---|
.. | .. |
---|
36 | 34 | #define EXYNOS5_FSEL_24MHZ 0x5 |
---|
37 | 35 | #define EXYNOS5_FSEL_50MHZ 0x7 |
---|
38 | 36 | |
---|
39 | | -/* EXYNOS5: USB 3.0 DRD PHY registers */ |
---|
| 37 | +/* Exynos5: USB 3.0 DRD PHY registers */ |
---|
40 | 38 | #define EXYNOS5_DRD_LINKSYSTEM 0x04 |
---|
41 | 39 | |
---|
42 | 40 | #define LINKSYSTEM_FLADJ_MASK (0x3f << 1) |
---|
.. | .. |
---|
183 | 181 | * @utmiclk: clock for utmi+ phy |
---|
184 | 182 | * @itpclk: clock for ITP generation |
---|
185 | 183 | * @drv_data: pointer to SoC level driver data structure |
---|
186 | | - * @phys[]: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY |
---|
| 184 | + * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY |
---|
187 | 185 | * instances each with its 'phy' and 'phy_cfg'. |
---|
188 | 186 | * @extrefclk: frequency select settings when using 'separate |
---|
189 | 187 | * reference clocks' for SS and HS operations |
---|
190 | 188 | * @ref_clk: reference clock to PHY block from which PHY's |
---|
191 | 189 | * operational clocks are derived |
---|
192 | | - * vbus: VBUS regulator for phy |
---|
193 | | - * vbus_boost: Boost regulator for VBUS present on few Exynos boards |
---|
| 190 | + * @vbus: VBUS regulator for phy |
---|
| 191 | + * @vbus_boost: Boost regulator for VBUS present on few Exynos boards |
---|
194 | 192 | */ |
---|
195 | 193 | struct exynos5_usbdrd_phy { |
---|
196 | 194 | struct device *dev; |
---|
.. | .. |
---|
559 | 557 | static int crport_handshake(struct exynos5_usbdrd_phy *phy_drd, |
---|
560 | 558 | u32 val, u32 cmd) |
---|
561 | 559 | { |
---|
562 | | - u32 usec = 100; |
---|
563 | 560 | unsigned int result; |
---|
| 561 | + int err; |
---|
564 | 562 | |
---|
565 | 563 | writel(val | cmd, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); |
---|
566 | 564 | |
---|
567 | | - do { |
---|
568 | | - result = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1); |
---|
569 | | - if (result & PHYREG1_CR_ACK) |
---|
570 | | - break; |
---|
571 | | - |
---|
572 | | - udelay(1); |
---|
573 | | - } while (usec-- > 0); |
---|
574 | | - |
---|
575 | | - if (!usec) { |
---|
576 | | - dev_err(phy_drd->dev, |
---|
577 | | - "CRPORT handshake timeout1 (0x%08x)\n", val); |
---|
578 | | - return -ETIME; |
---|
| 565 | + err = readl_poll_timeout(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1, |
---|
| 566 | + result, (result & PHYREG1_CR_ACK), 1, 100); |
---|
| 567 | + if (err == -ETIMEDOUT) { |
---|
| 568 | + dev_err(phy_drd->dev, "CRPORT handshake timeout1 (0x%08x)\n", val); |
---|
| 569 | + return err; |
---|
579 | 570 | } |
---|
580 | | - |
---|
581 | | - usec = 100; |
---|
582 | 571 | |
---|
583 | 572 | writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); |
---|
584 | 573 | |
---|
585 | | - do { |
---|
586 | | - result = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1); |
---|
587 | | - if (!(result & PHYREG1_CR_ACK)) |
---|
588 | | - break; |
---|
589 | | - |
---|
590 | | - udelay(1); |
---|
591 | | - } while (usec-- > 0); |
---|
592 | | - |
---|
593 | | - if (!usec) { |
---|
594 | | - dev_err(phy_drd->dev, |
---|
595 | | - "CRPORT handshake timeout2 (0x%08x)\n", val); |
---|
596 | | - return -ETIME; |
---|
| 574 | + err = readl_poll_timeout(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1, |
---|
| 575 | + result, !(result & PHYREG1_CR_ACK), 1, 100); |
---|
| 576 | + if (err == -ETIMEDOUT) { |
---|
| 577 | + dev_err(phy_drd->dev, "CRPORT handshake timeout2 (0x%08x)\n", val); |
---|
| 578 | + return err; |
---|
597 | 579 | } |
---|
598 | 580 | |
---|
599 | 581 | return 0; |
---|
.. | .. |
---|
958 | 940 | .driver = { |
---|
959 | 941 | .of_match_table = exynos5_usbdrd_phy_of_match, |
---|
960 | 942 | .name = "exynos5_usb3drd_phy", |
---|
| 943 | + .suppress_bind_attrs = true, |
---|
961 | 944 | } |
---|
962 | 945 | }; |
---|
963 | 946 | |
---|
964 | 947 | module_platform_driver(exynos5_usb3drd_phy); |
---|
965 | | -MODULE_DESCRIPTION("Samsung EXYNOS5 SoCs USB 3.0 DRD controller PHY driver"); |
---|
| 948 | +MODULE_DESCRIPTION("Samsung Exynos5 SoCs USB 3.0 DRD controller PHY driver"); |
---|
966 | 949 | MODULE_AUTHOR("Vivek Gautam <gautam.vivek@samsung.com>"); |
---|
967 | 950 | MODULE_LICENSE("GPL v2"); |
---|
968 | 951 | MODULE_ALIAS("platform:exynos5_usb3drd_phy"); |
---|