usb: chipidea: core: modernize ulpi reset gpio handling
Some checks are pending
Maintenance / sync_branches (push) Waiting to run
Maintenance / assert (push) Blocked by required conditions
Kernel build / checks (push) Waiting to run
Kernel build / build_gcc_x86_64 (push) Blocked by required conditions
Kernel build / build_llvm_x86_64 (push) Blocked by required conditions
Kernel build / build_gcc_aarch64 (push) Blocked by required conditions
Kernel build / build_gcc_arm (push) Waiting to run
Kernel build / assert_checks (push) Blocked by required conditions
Kernel build / conditional_xlnx (push) Blocked by required conditions
Kernel build / build_gcc_arm_zynq_xcomm_adv7511_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_socfpga_adi_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_zynq_pluto_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_zynq_m2k_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_aarch64_adi_zynqmp_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_adi_versal_defconfig (push) Blocked by required conditions
Kernel build / many_devicetrees (push) Blocked by required conditions
Kernel build / assert_build_xlnx (push) Blocked by required conditions
Kernel build / conditional_rpi (push) Blocked by required conditions
Kernel build / build_gcc_arm_adi_bcm2709_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_adi_bcm2711_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_adi_bcmrpi_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_aarch64_adi_bcm2711_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_aarch64_adi_bcm2712_defconfig (push) Blocked by required conditions
Kernel build / assert_build_rpi (push) Blocked by required conditions
Kernel build / conditional_adsp (push) Blocked by required conditions
Kernel build / build_gcc_arm_sc573-ezkit_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_sc589-mini_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_sc594-som-ezkit_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_arm_sc594-som-ezlite_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_aarch64_sc598-som-ezkit_defconfig (push) Blocked by required conditions
Kernel build / build_gcc_aarch64_sc598-som-ezlite_defconfig (push) Blocked by required conditions
Kernel build / assert_build_adsp (push) Blocked by required conditions
Kernel build / conditional_oran (push) Blocked by required conditions
Kernel build / build_gcc_aarch64_adrv906x-eval_defconfig (push) Blocked by required conditions
Kernel build / assert_build_oran (push) Blocked by required conditions

The ulpi reset gpio code (which is a patch owned by us) was still using
the legacy gpio API which brings some pain from times to times whem
merging to a new kernel version (ex: this merge a macro was dropped from
upstream). Hence, use the proper GPIO consumer API.

On top of that, correctly handle the pin polarity. The pins is active
low so this means we want to request the GPIO asserted to reset the phy
(hence GPIOD_OUT_HIGH) and then bring the device out of reset by
deaserting the pin (hence passing 0 in gpiod_set_value_cansleep().
Things worked because we "cheated" in DT by saying the pin is active
high and then requesting it in the deasserted state (setting the pin to 0
and effectively assert/reset it), Then asserting it by passing 1 to
gpiod_set_value_cansleep() which in fact was deasserting the pin.

While at it, use fsleep() instead of msleep().

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
This commit is contained in:
Nuno Sá
2025-08-08 14:58:54 +01:00
committed by Nuno Sá
parent 3fb6d4bad9
commit 4fa8ceaed4

View File

@@ -18,7 +18,7 @@
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/extcon.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/module.h>
@@ -36,7 +36,6 @@
#include <linux/usb/of.h>
#include <linux/usb/ulpi.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/phy.h>
#include <linux/regulator/consumer.h>
#include <linux/usb/ehci_def.h>
@@ -993,20 +992,22 @@ static void ci_get_otg_capable(struct ci_hdrc *ci)
static int ci_hdrc_create_ulpi_phy(struct device *dev, struct ci_hdrc *ci)
{
struct usb_phy *ulpi;
int reset_gpio;
int ret;
struct gpio_desc *reset_gpio;
reset_gpio = of_get_named_gpio(dev->parent->of_node, "xlnx,phy-reset-gpio", 0);
if (gpio_is_valid(reset_gpio)) {
ret = devm_gpio_request_one(dev, reset_gpio,
GPIOF_OUT_INIT_LOW, "ulpi resetb");
if (ret) {
dev_err(dev, "Failed to request ULPI reset gpio: %d\n", ret);
reset_gpio = devm_gpiod_get_optional(dev->parent, "xlnx,phy-reset-gpio",
GPIOD_OUT_HIGH);
if (IS_ERR(reset_gpio))
return dev_err_probe(dev, PTR_ERR(reset_gpio), "Failed to get ULPI reset gpio\n");
if (reset_gpio) {
int ret;
ret = gpiod_set_consumer_name(reset_gpio, "ulpi resetb");
if (ret)
return ret;
}
msleep(5);
gpio_set_value_cansleep(reset_gpio, 1);
msleep(1);
fsleep(5);
gpiod_set_value_cansleep(reset_gpio, 0);
fsleep(1);
}
ulpi = otg_ulpi_create(&ulpi_viewport_access_ops,