diff options
author | Tom Rini <trini@konsulko.com> | 2021-09-27 09:45:36 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-09-27 09:45:36 -0400 |
commit | e908d20fcbd847e17345591fc171b59d9a156516 (patch) | |
tree | def104237fd9b8888a37a5c3378b4ef7e26b6d43 /drivers/usb/host/xhci-pci.c | |
parent | bb38d77ca779cc8bdad3d4ceb6cecc687f4987c2 (diff) | |
parent | 0b9bcf665cd98fe9db0956c894006b250a7d465f (diff) | |
download | u-boot-e908d20fcbd847e17345591fc171b59d9a156516.tar.gz |
Merge tag 'v2021.10-rc5' into next
Prepare v2021.10-rc5
Diffstat (limited to 'drivers/usb/host/xhci-pci.c')
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index aaa243f2917..630bc20be1e 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -7,12 +7,18 @@ #include <common.h> #include <dm.h> +#include <dm/device_compat.h> #include <init.h> #include <log.h> #include <pci.h> +#include <reset.h> #include <usb.h> #include <usb/xhci.h> +struct xhci_pci_plat { + struct reset_ctl reset; +}; + static int xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr, struct xhci_hcor **ret_hcor) { @@ -45,15 +51,53 @@ static int xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr, static int xhci_pci_probe(struct udevice *dev) { + struct xhci_pci_plat *plat = dev_get_plat(dev); struct xhci_hccr *hccr; struct xhci_hcor *hcor; int ret; + ret = reset_get_by_index(dev, 0, &plat->reset); + if (ret && ret != -ENOENT && ret != -ENOTSUPP) { + dev_err(dev, "failed to get reset\n"); + return ret; + } + + if (reset_valid(&plat->reset)) { + ret = reset_assert(&plat->reset); + if (ret) + goto err_reset; + + ret = reset_deassert(&plat->reset); + if (ret) + goto err_reset; + } + ret = xhci_pci_init(dev, &hccr, &hcor); if (ret) - return ret; + goto err_reset; + + ret = xhci_register(dev, hccr, hcor); + if (ret) + goto err_reset; + + return 0; + +err_reset: + if (reset_valid(&plat->reset)) + reset_free(&plat->reset); + + return ret; +} + +static int xhci_pci_remove(struct udevice *dev) +{ + struct xhci_pci_plat *plat = dev_get_plat(dev); - return xhci_register(dev, hccr, hcor); + xhci_deregister(dev); + if (reset_valid(&plat->reset)) + reset_free(&plat->reset); + + return 0; } static const struct udevice_id xhci_pci_ids[] = { @@ -65,10 +109,10 @@ U_BOOT_DRIVER(xhci_pci) = { .name = "xhci_pci", .id = UCLASS_USB, .probe = xhci_pci_probe, - .remove = xhci_deregister, + .remove = xhci_pci_remove, .of_match = xhci_pci_ids, .ops = &xhci_usb_ops, - .plat_auto = sizeof(struct usb_plat), + .plat_auto = sizeof(struct xhci_pci_plat), .priv_auto = sizeof(struct xhci_ctrl), .flags = DM_FLAG_OS_PREPARE | DM_FLAG_ALLOC_PRIV_DMA, }; |