generic_ehci: Enable all phys and resets
The number of phys and resets is not defined and it controller dependent so enable/disable every one of them.
This commit is contained in:
parent
fbf39b9767
commit
150c95edfe
@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/extres/clk/clk.h>
|
#include <dev/extres/clk/clk.h>
|
||||||
#include <dev/extres/hwreset/hwreset.h>
|
#include <dev/extres/hwreset/hwreset.h>
|
||||||
#include <dev/extres/phy/phy.h>
|
#include <dev/extres/phy/phy.h>
|
||||||
|
#include <dev/extres/phy/phy_usb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "generic_usb_if.h"
|
#include "generic_usb_if.h"
|
||||||
@ -69,15 +70,23 @@ struct clk_list {
|
|||||||
TAILQ_ENTRY(clk_list) next;
|
TAILQ_ENTRY(clk_list) next;
|
||||||
clk_t clk;
|
clk_t clk;
|
||||||
};
|
};
|
||||||
|
struct phy_list {
|
||||||
|
TAILQ_ENTRY(phy_list) next;
|
||||||
|
phy_t phy;
|
||||||
|
};
|
||||||
|
struct hwrst_list {
|
||||||
|
TAILQ_ENTRY(hwrst_list) next;
|
||||||
|
hwreset_t rst;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct generic_ohci_softc {
|
struct generic_ohci_softc {
|
||||||
ohci_softc_t ohci_sc;
|
ohci_softc_t ohci_sc;
|
||||||
|
|
||||||
#ifdef EXT_RESOURCES
|
#ifdef EXT_RESOURCES
|
||||||
hwreset_t rst;
|
TAILQ_HEAD(, clk_list) clk_list;
|
||||||
phy_t phy;
|
TAILQ_HEAD(, phy_list) phy_list;
|
||||||
TAILQ_HEAD(, clk_list) clk_list;
|
TAILQ_HEAD(, hwrst_list) rst_list;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,8 +115,11 @@ generic_ohci_attach(device_t dev)
|
|||||||
#ifdef EXT_RESOURCES
|
#ifdef EXT_RESOURCES
|
||||||
int off;
|
int off;
|
||||||
struct clk_list *clkp;
|
struct clk_list *clkp;
|
||||||
|
struct phy_list *phyp;
|
||||||
|
struct hwrst_list *rstp;
|
||||||
clk_t clk;
|
clk_t clk;
|
||||||
phandle_t node;
|
phy_t phy;
|
||||||
|
hwreset_t rst;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sc->ohci_sc.sc_bus.parent = dev;
|
sc->ohci_sc.sc_bus.parent = dev;
|
||||||
@ -115,8 +127,6 @@ generic_ohci_attach(device_t dev)
|
|||||||
sc->ohci_sc.sc_bus.devices_max = OHCI_MAX_DEVICES;
|
sc->ohci_sc.sc_bus.devices_max = OHCI_MAX_DEVICES;
|
||||||
sc->ohci_sc.sc_bus.dma_bits = 32;
|
sc->ohci_sc.sc_bus.dma_bits = 32;
|
||||||
|
|
||||||
node = ofw_bus_get_node(dev);
|
|
||||||
|
|
||||||
/* get all DMA memory */
|
/* get all DMA memory */
|
||||||
if (usb_bus_mem_alloc_all(&sc->ohci_sc.sc_bus,
|
if (usb_bus_mem_alloc_all(&sc->ohci_sc.sc_bus,
|
||||||
USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
|
USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
|
||||||
@ -176,22 +186,34 @@ generic_ohci_attach(device_t dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* De-assert reset */
|
/* De-assert reset */
|
||||||
if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) == 0) {
|
TAILQ_INIT(&sc->rst_list);
|
||||||
err = hwreset_deassert(sc->rst);
|
for (off = 0; hwreset_get_by_ofw_idx(dev, 0, off, &rst) == 0; off++) {
|
||||||
|
err = hwreset_deassert(rst);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
device_printf(dev, "Could not de-assert reset %d\n",
|
device_printf(dev, "Could not de-assert reset\n");
|
||||||
off);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
rstp = malloc(sizeof(*rstp), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||||
|
rstp->rst = rst;
|
||||||
|
TAILQ_INSERT_TAIL(&sc->rst_list, rstp, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable phy */
|
/* Enable phy */
|
||||||
if (phy_get_by_ofw_idx(dev, node, 0, &sc->phy) == 0) {
|
TAILQ_INIT(&sc->phy_list);
|
||||||
err = phy_enable(sc->phy);
|
for (off = 0; phy_get_by_ofw_idx(dev, 0, off, &phy) == 0; off++) {
|
||||||
|
err = phy_usb_set_mode(phy, PHY_USB_MODE_HOST);
|
||||||
|
if (err != 0) {
|
||||||
|
device_printf(dev, "Could not set phy to host mode\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
err = phy_enable(phy);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
device_printf(dev, "Could not enable phy\n");
|
device_printf(dev, "Could not enable phy\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
phyp = malloc(sizeof(*phyp), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||||
|
phyp->phy = phy;
|
||||||
|
TAILQ_INSERT_TAIL(&sc->phy_list, phyp, next);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -219,6 +241,8 @@ generic_ohci_detach(device_t dev)
|
|||||||
int err;
|
int err;
|
||||||
#ifdef EXT_RESOURCES
|
#ifdef EXT_RESOURCES
|
||||||
struct clk_list *clk, *clk_tmp;
|
struct clk_list *clk, *clk_tmp;
|
||||||
|
struct phy_list *phy, *phy_tmp;
|
||||||
|
struct hwrst_list *rst, *rst_tmp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* during module unload there are lots of children leftover */
|
/* during module unload there are lots of children leftover */
|
||||||
@ -260,11 +284,21 @@ generic_ohci_detach(device_t dev)
|
|||||||
|
|
||||||
#ifdef EXT_RESOURCES
|
#ifdef EXT_RESOURCES
|
||||||
/* Disable phy */
|
/* Disable phy */
|
||||||
if (sc->phy) {
|
TAILQ_FOREACH_SAFE(phy, &sc->phy_list, next, phy_tmp) {
|
||||||
err = phy_disable(sc->phy);
|
err = phy_disable(phy->phy);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
device_printf(dev, "Could not disable phy\n");
|
device_printf(dev, "Could not disable phy\n");
|
||||||
phy_release(sc->phy);
|
phy_release(phy->phy);
|
||||||
|
TAILQ_REMOVE(&sc->phy_list, phy, next);
|
||||||
|
free(phy, M_DEVBUF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assert reset */
|
||||||
|
TAILQ_FOREACH_SAFE(rst, &sc->rst_list, next, rst_tmp) {
|
||||||
|
hwreset_assert(rst->rst);
|
||||||
|
hwreset_release(rst->rst);
|
||||||
|
TAILQ_REMOVE(&sc->rst_list, rst, next);
|
||||||
|
free(rst, M_DEVBUF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable clock */
|
/* Disable clock */
|
||||||
@ -280,14 +314,6 @@ generic_ohci_detach(device_t dev)
|
|||||||
TAILQ_REMOVE(&sc->clk_list, clk, next);
|
TAILQ_REMOVE(&sc->clk_list, clk, next);
|
||||||
free(clk, M_DEVBUF);
|
free(clk, M_DEVBUF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* De-assert reset */
|
|
||||||
if (sc->rst) {
|
|
||||||
err = hwreset_assert(sc->rst);
|
|
||||||
if (err != 0)
|
|
||||||
device_printf(dev, "Could not assert reset\n");
|
|
||||||
hwreset_release(sc->rst);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (GENERIC_USB_DEINIT(dev) != 0)
|
if (GENERIC_USB_DEINIT(dev) != 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user