summaryrefslogtreecommitdiff
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2015-03-25 18:22:27 (GMT)
committerSimon Glass <sjg@chromium.org>2015-04-18 17:11:24 (GMT)
commitdeb8508c518b8e49f2cd3199861e639d9eeebd9f (patch)
tree910919cd533a774a43bb0263eef5b9f3f6880710 /drivers/usb/host/ehci-hcd.c
parent7372b5bd318515c0e756a96e1f730a3ff119bd31 (diff)
downloadu-boot-deb8508c518b8e49f2cd3199861e639d9eeebd9f.tar.xz
dm: usb: Drop the EHCI weak functions
These are a pain with driver model because we might have different EHCI drivers which want to implement them differently. Now that they use consistent function signatures, we can in good conscience move them to a struct. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Marek Vasut <marex@denx.de> Fix non-driver-model EHCI to set up the EHCI operations correctly: Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c55
1 files changed, 45 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 9a9ec01..c6696aa 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -124,12 +124,12 @@ static struct ehci_ctrl *ehci_get_ctrl(struct usb_device *udev)
return udev->controller;
}
-__weak int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
+static int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
{
return PORTSC_PSPD(reg);
}
-__weak void ehci_set_usbmode(struct ehci_ctrl *ctrl)
+static void ehci_set_usbmode(struct ehci_ctrl *ctrl)
{
uint32_t tmp;
uint32_t *reg_ptr;
@@ -143,13 +143,13 @@ __weak void ehci_set_usbmode(struct ehci_ctrl *ctrl)
ehci_writel(reg_ptr, tmp);
}
-__weak void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+static void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
uint32_t *reg)
{
mdelay(50);
}
-__weak uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
+static uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
{
if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
/* Printing the message would cause a scan failure! */
@@ -178,6 +178,7 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
static int ehci_reset(int index)
{
+ struct ehci_ctrl *ctrl = &ehcic[index];
uint32_t cmd;
int ret = 0;
@@ -192,7 +193,7 @@ static int ehci_reset(int index)
}
if (ehci_is_TDI())
- ehci_set_usbmode(&ehcic[index]);
+ ctrl->ops.set_usb_mode(&ehcic[index]);
#ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
@@ -691,7 +692,7 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
- status_reg = ehci_get_portsc_register(ctrl, port - 1);
+ status_reg = ctrl->ops.get_portsc_register(ctrl, port - 1);
if (!status_reg)
return -1;
break;
@@ -786,7 +787,7 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
if (ehci_is_TDI()) {
- switch (ehci_get_port_speed(ctrl, reg)) {
+ switch (ctrl->ops.get_port_speed(ctrl, reg)) {
case PORTSC_PSPD_FS:
break;
case PORTSC_PSPD_LS:
@@ -848,7 +849,7 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
* usb 2.0 specification say 50 ms resets on
* root
*/
- ehci_powerup_fixup(ctrl, status_reg, &reg);
+ ctrl->ops.powerup_fixup(ctrl, status_reg, &reg);
ehci_writel(status_reg, reg & ~EHCI_PS_PR);
/*
@@ -935,9 +936,37 @@ unknown:
return -1;
}
-void ehci_set_controller_priv(int index, void *priv)
+const struct ehci_ops default_ehci_ops = {
+ .set_usb_mode = ehci_set_usbmode,
+ .get_port_speed = ehci_get_port_speed,
+ .powerup_fixup = ehci_powerup_fixup,
+ .get_portsc_register = ehci_get_portsc_register,
+};
+
+static void ehci_setup_ops(struct ehci_ctrl *ctrl, const struct ehci_ops *ops)
+{
+ if (!ops) {
+ ctrl->ops = default_ehci_ops;
+ } else {
+ ctrl->ops = *ops;
+ if (!ctrl->ops.set_usb_mode)
+ ctrl->ops.set_usb_mode = ehci_set_usbmode;
+ if (!ctrl->ops.get_port_speed)
+ ctrl->ops.get_port_speed = ehci_get_port_speed;
+ if (!ctrl->ops.powerup_fixup)
+ ctrl->ops.powerup_fixup = ehci_powerup_fixup;
+ if (!ctrl->ops.get_portsc_register)
+ ctrl->ops.get_portsc_register =
+ ehci_get_portsc_register;
+ }
+}
+
+void ehci_set_controller_priv(int index, void *priv, const struct ehci_ops *ops)
{
- ehcic[index].priv = priv;
+ struct ehci_ctrl *ctrl = &ehcic[index];
+
+ ctrl->priv = priv;
+ ehci_setup_ops(ctrl, ops);
}
void *ehci_get_controller_priv(int index)
@@ -1066,6 +1095,12 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
uint tweaks = 0;
int rc;
+ /**
+ * Set ops to default_ehci_ops, ehci_hcd_init should call
+ * ehci_set_controller_priv to change any of these function pointers.
+ */
+ ctrl->ops = default_ehci_ops;
+
rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor);
if (rc)
return rc;