]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/usb/host/ehci-generic.c
03f8d321af13e3ddb04c46ae9a66d16b82defe73
2 * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
4 * SPDX-License-Identifier: GPL-2.0+
10 #include <generic-phy.h>
17 * Even though here we don't explicitly use "struct ehci_ctrl"
18 * ehci_register() expects it to be the first thing that resides in
19 * device's private data.
22 struct ehci_ctrl ctrl
;
24 struct reset_ctl
*resets
;
30 static int ehci_usb_probe(struct udevice
*dev
)
32 struct generic_ehci
*priv
= dev_get_priv(dev
);
33 struct ehci_hccr
*hccr
;
34 struct ehci_hcor
*hcor
;
35 int i
, err
, ret
, clock_nb
, reset_nb
;
38 priv
->clock_count
= 0;
39 clock_nb
= ofnode_count_phandle_with_args(dev_ofnode(dev
), "clocks",
42 priv
->clocks
= devm_kcalloc(dev
, clock_nb
, sizeof(struct clk
),
47 for (i
= 0; i
< clock_nb
; i
++) {
48 err
= clk_get_by_index(dev
, i
, &priv
->clocks
[i
]);
52 err
= clk_enable(&priv
->clocks
[i
]);
54 error("failed to enable clock %d\n", i
);
55 clk_free(&priv
->clocks
[i
]);
61 if (clock_nb
!= -ENOENT
) {
62 error("failed to get clock phandle(%d)\n", clock_nb
);
67 priv
->reset_count
= 0;
68 reset_nb
= ofnode_count_phandle_with_args(dev_ofnode(dev
), "resets",
71 priv
->resets
= devm_kcalloc(dev
, reset_nb
,
72 sizeof(struct reset_ctl
),
77 for (i
= 0; i
< reset_nb
; i
++) {
78 err
= reset_get_by_index(dev
, i
, &priv
->resets
[i
]);
82 if (reset_deassert(&priv
->resets
[i
])) {
83 error("failed to deassert reset %d\n", i
);
84 reset_free(&priv
->resets
[i
]);
90 if (reset_nb
!= -ENOENT
) {
91 error("failed to get reset phandle(%d)\n", reset_nb
);
96 err
= generic_phy_get_by_index(dev
, 0, &priv
->phy
);
99 error("failed to get usb phy\n");
104 err
= generic_phy_init(&priv
->phy
);
106 error("failed to init usb phy\n");
111 hccr
= map_physmem(devfdt_get_addr(dev
), 0x100, MAP_NOCACHE
);
112 hcor
= (struct ehci_hcor
*)((uintptr_t)hccr
+
113 HC_LENGTH(ehci_readl(&hccr
->cr_capbase
)));
115 err
= ehci_register(dev
, hccr
, hcor
, NULL
, 0, USB_INIT_HOST
);
122 if (generic_phy_valid(&priv
->phy
)) {
123 ret
= generic_phy_exit(&priv
->phy
);
125 error("failed to release phy\n");
129 ret
= reset_release_all(priv
->resets
, priv
->reset_count
);
131 error("failed to assert all resets\n");
133 ret
= clk_release_all(priv
->clocks
, priv
->clock_count
);
135 error("failed to disable all clocks\n");
140 static int ehci_usb_remove(struct udevice
*dev
)
142 struct generic_ehci
*priv
= dev_get_priv(dev
);
145 ret
= ehci_deregister(dev
);
149 if (generic_phy_valid(&priv
->phy
)) {
150 ret
= generic_phy_exit(&priv
->phy
);
155 ret
= reset_release_all(priv
->resets
, priv
->reset_count
);
159 return clk_release_all(priv
->clocks
, priv
->clock_count
);
162 static const struct udevice_id ehci_usb_ids
[] = {
163 { .compatible
= "generic-ehci" },
167 U_BOOT_DRIVER(ehci_generic
) = {
168 .name
= "ehci_generic",
170 .of_match
= ehci_usb_ids
,
171 .probe
= ehci_usb_probe
,
172 .remove
= ehci_usb_remove
,
173 .ops
= &ehci_usb_ops
,
174 .priv_auto_alloc_size
= sizeof(struct generic_ehci
),
175 .flags
= DM_FLAG_ALLOC_PRIV_DMA
,