From patchwork Wed Jul 8 02:53:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 492689 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id E89A1140D19 for ; Wed, 8 Jul 2015 12:54:59 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b=YmAvOh2i; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0104E4B935; Wed, 8 Jul 2015 04:54:55 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FiMkxmfk3stj; Wed, 8 Jul 2015 04:54:54 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 629C44B939; Wed, 8 Jul 2015 04:54:42 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C41A74B8F8 for ; Wed, 8 Jul 2015 04:54:30 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8JLzPsUtkjlv for ; Wed, 8 Jul 2015 04:54:30 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-ig0-f175.google.com (mail-ig0-f175.google.com [209.85.213.175]) by theia.denx.de (Postfix) with ESMTPS id 18FCC4B901 for ; Wed, 8 Jul 2015 04:54:26 +0200 (CEST) Received: by igcqs7 with SMTP id qs7so46876179igc.0 for ; Tue, 07 Jul 2015 19:54:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=SF4xknTqdjWruhEfyRJte6nICpBcesJjzv3NFnGLpGo=; b=YmAvOh2ixNs2BiMPydbleMHZ4Tfo2EntHRLm2nolacT0eYtzKHpBuKJ96Y0cAMMHq2 1Cuf5d0ksIYhiOuFKK+aEGwdOPfog2yc6cJGFWjH6xFyBYSrGhl5CRNc5IX5YPIgUoQx /2oPn0jAHt2OPm24iwpWi1tq9iOQzoDh1Apl2lO4ayES7RIE7FO10FZHLmXpbgw7ICYN 9swILnTzevPTG4W7JVVjXbwFChjzpTm6obvFGGxrIfxRAI9vndwF6RDpaXGu60FneSfn T6QDRqmsUtM7E4drCZ2vfUHBPXSaCa23B6pc2cDTaLf1DMTD0kbCC+Reno13w5aJFWw0 KbSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=SF4xknTqdjWruhEfyRJte6nICpBcesJjzv3NFnGLpGo=; b=fR1C58ZMJcasFILNQWLl2V4gIm8vZ51F78cb9mgQmAd8Eb4E4tXBnLd3UQbpRJrUbE Zvqtng1rpamNSijJ4GPw60BcZwAmFvvEdp0nIBtcI0cUARQ05qX1trPfAq89AC0p0xgc tMs/xt4nhgLpXAW1egZA6vTyWpgM7snsFzY/2e8lj8QZDMTQxrVtt+7OobVTdtrR1psB ogpe0C0WOo7bB/8hbJUnVDsDZpuS3px2LUkcw/rTa0BpNIyZi1jHxYidoS8DzWxms0Ie yugtzZn2/1vUCgR3Y5lEV5AMSjBDKjyIMT0KicxA/TXV3W7HRUlnMirTCkqtJZ9ekbbd Nw0g== X-Gm-Message-State: ALoCoQnRa43xrpwQFPag0fFjsE0NWsdGqa3mhraA/DIRgnqZ7rOGv0cCpZnxI1TX/FDTD6vBb4f2 X-Received: by 10.107.38.129 with SMTP id m123mr6016086iom.22.1436324065400; Tue, 07 Jul 2015 19:54:25 -0700 (PDT) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by smtp.gmail.com with ESMTPSA id j3sm939044igx.21.2015.07.07.19.54.23 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Jul 2015 19:54:23 -0700 (PDT) Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 83FEE220E61; Tue, 7 Jul 2015 20:54:22 -0600 (MDT) From: Simon Glass To: U-Boot Mailing List Date: Tue, 7 Jul 2015 20:53:36 -0600 Message-Id: <1436324032-17931-5-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.4.3.573.g4eafbef In-Reply-To: <1436324032-17931-1-git-send-email-sjg@chromium.org> References: <1436324032-17931-1-git-send-email-sjg@chromium.org> Cc: Marek Vasut , Masahiro Yamada , Stephen Warren , Joe Hershberger , Pavel Machek , Oleksandr Tymoshenko , Tom Rini Subject: [U-Boot] [PATCH 04/20] dm: usb: Prepare dwc2 driver for driver-model conversion X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Put all global data in a structure and move (what will be) common code into common functions. This will make the driver-model conversion much easier. Signed-off-by: Simon Glass --- drivers/usb/host/dwc2.c | 150 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 100 insertions(+), 50 deletions(-) diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index eee60a2..366e025 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -21,18 +21,22 @@ #define DWC2_STATUS_BUF_SIZE 64 #define DWC2_DATA_BUF_SIZE (64 * 1024) -/* We need doubleword-aligned buffers for DMA transfers */ -DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer, DWC2_DATA_BUF_SIZE, 8); -DEFINE_ALIGN_BUFFER(uint8_t, status_buffer, DWC2_STATUS_BUF_SIZE, 8); - #define MAX_DEVICE 16 #define MAX_ENDPOINT 16 -static int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; -static int root_hub_devnum; +struct dwc2_priv { + uint8_t *aligned_buffer; + uint8_t *status_buffer; + int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; + struct dwc2_core_regs *regs; + int root_hub_devnum; +}; + +/* We need doubleword-aligned buffers for DMA transfers */ +DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer_addr, DWC2_DATA_BUF_SIZE, 8); +DEFINE_ALIGN_BUFFER(uint8_t, status_buffer_addr, DWC2_STATUS_BUF_SIZE, 8); -static struct dwc2_core_regs *regs = - (struct dwc2_core_regs *)CONFIG_USB_DWC2_REG_ADDR; +static struct dwc2_priv local; /* * DWC2 IP interface @@ -428,7 +432,8 @@ static void dwc_otg_hc_init(struct dwc2_core_regs *regs, uint8_t hc_num, * DWC2 to USB API interface */ /* Direction: In ; Request: Status */ -static int dwc_otg_submit_rh_msg_in_status(struct usb_device *dev, void *buffer, +static int dwc_otg_submit_rh_msg_in_status(struct dwc2_core_regs *regs, + struct usb_device *dev, void *buffer, int txlen, struct devrequest *cmd) { uint32_t hprt0 = 0; @@ -602,13 +607,13 @@ static int dwc_otg_submit_rh_msg_in_configuration(struct usb_device *dev, } /* Direction: In */ -static int dwc_otg_submit_rh_msg_in(struct usb_device *dev, - void *buffer, int txlen, - struct devrequest *cmd) +static int dwc_otg_submit_rh_msg_in(struct dwc2_priv *priv, + struct usb_device *dev, void *buffer, + int txlen, struct devrequest *cmd) { switch (cmd->request) { case USB_REQ_GET_STATUS: - return dwc_otg_submit_rh_msg_in_status(dev, buffer, + return dwc_otg_submit_rh_msg_in_status(priv->regs, dev, buffer, txlen, cmd); case USB_REQ_GET_DESCRIPTOR: return dwc_otg_submit_rh_msg_in_descriptor(dev, buffer, @@ -623,10 +628,12 @@ static int dwc_otg_submit_rh_msg_in(struct usb_device *dev, } /* Direction: Out */ -static int dwc_otg_submit_rh_msg_out(struct usb_device *dev, - void *buffer, int txlen, - struct devrequest *cmd) +static int dwc_otg_submit_rh_msg_out(struct dwc2_priv *priv, + struct usb_device *dev, + void *buffer, int txlen, + struct devrequest *cmd) { + struct dwc2_core_regs *regs = priv->regs; int len = 0; int stat = 0; uint16_t bmrtype_breq = cmd->requesttype | (cmd->request << 8); @@ -673,7 +680,7 @@ static int dwc_otg_submit_rh_msg_out(struct usb_device *dev, } break; case (USB_REQ_SET_ADDRESS << 8): - root_hub_devnum = wValue; + priv->root_hub_devnum = wValue; break; case (USB_REQ_SET_CONFIGURATION << 8): break; @@ -690,8 +697,8 @@ static int dwc_otg_submit_rh_msg_out(struct usb_device *dev, return stat; } -static int dwc_otg_submit_rh_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int txlen, +static int dwc_otg_submit_rh_msg(struct dwc2_priv *priv, struct usb_device *dev, + unsigned long pipe, void *buffer, int txlen, struct devrequest *cmd) { int stat = 0; @@ -702,16 +709,17 @@ static int dwc_otg_submit_rh_msg(struct usb_device *dev, unsigned long pipe, } if (cmd->requesttype & USB_DIR_IN) - stat = dwc_otg_submit_rh_msg_in(dev, buffer, txlen, cmd); + stat = dwc_otg_submit_rh_msg_in(priv, dev, buffer, txlen, cmd); else - stat = dwc_otg_submit_rh_msg_out(dev, buffer, txlen, cmd); + stat = dwc_otg_submit_rh_msg_out(priv, dev, buffer, txlen, cmd); mdelay(1); return stat; } -int wait_for_chhltd(uint32_t *sub, int *toggle, bool ignore_ack) +int wait_for_chhltd(struct dwc2_core_regs *regs, uint32_t *sub, int *toggle, + bool ignore_ack) { uint32_t hcint_comp_hlt_ack = DWC2_HCINT_XFERCOMP | DWC2_HCINT_CHHLTD; struct dwc2_hc_regs *hc_regs = ®s->hc_regs[DWC2_HC_CHANNEL]; @@ -751,9 +759,11 @@ static int dwc2_eptype[] = { DWC2_HCCHAR_EPTYPE_BULK, }; -int chunk_msg(struct usb_device *dev, unsigned long pipe, int *pid, int in, - void *buffer, int len, bool ignore_ack) +int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev, + unsigned long pipe, int *pid, int in, void *buffer, int len, + bool ignore_ack) { + struct dwc2_core_regs *regs = priv->regs; struct dwc2_hc_regs *hc_regs = ®s->hc_regs[DWC2_HC_CHANNEL]; int devnum = usb_pipedevice(pipe); int ep = usb_pipeendpoint(pipe); @@ -802,10 +812,12 @@ int chunk_msg(struct usb_device *dev, unsigned long pipe, int *pid, int in, (*pid << DWC2_HCTSIZ_PID_OFFSET), &hc_regs->hctsiz); - if (!in) - memcpy(aligned_buffer, (char *)buffer + done, len); + if (!in) { + memcpy(priv->aligned_buffer, (char *)buffer + done, + len); + } - writel(phys_to_bus((unsigned long)aligned_buffer), + writel(phys_to_bus((unsigned long)priv->aligned_buffer), &hc_regs->hcdma); /* Set host channel enable after all other setup is complete. */ @@ -814,13 +826,13 @@ int chunk_msg(struct usb_device *dev, unsigned long pipe, int *pid, int in, (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN); - ret = wait_for_chhltd(&sub, pid, ignore_ack); + ret = wait_for_chhltd(regs, &sub, pid, ignore_ack); if (ret) break; if (in) { xfer_len -= sub; - memcpy(buffer + done, aligned_buffer, xfer_len); + memcpy(buffer + done, priv->aligned_buffer, xfer_len); if (sub) stop_transfer = 1; } @@ -839,43 +851,45 @@ int chunk_msg(struct usb_device *dev, unsigned long pipe, int *pid, int in, } /* U-Boot USB transmission interface */ -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int len) +int _submit_bulk_msg(struct dwc2_priv *priv, struct usb_device *dev, + unsigned long pipe, void *buffer, int len) { int devnum = usb_pipedevice(pipe); int ep = usb_pipeendpoint(pipe); - if (devnum == root_hub_devnum) { + if (devnum == priv->root_hub_devnum) { dev->status = 0; return -EINVAL; } - return chunk_msg(dev, pipe, &bulk_data_toggle[devnum][ep], + return chunk_msg(priv, dev, pipe, &priv->bulk_data_toggle[devnum][ep], usb_pipein(pipe), buffer, len, true); } -int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int len, struct devrequest *setup) +static int _submit_control_msg(struct dwc2_priv *priv, struct usb_device *dev, + unsigned long pipe, void *buffer, int len, + struct devrequest *setup) { int devnum = usb_pipedevice(pipe); int pid, ret, act_len; /* For CONTROL endpoint pid should start with DATA1 */ int status_direction; - if (devnum == root_hub_devnum) { + if (devnum == priv->root_hub_devnum) { dev->status = 0; dev->speed = USB_SPEED_HIGH; - return dwc_otg_submit_rh_msg(dev, pipe, buffer, len, setup); + return dwc_otg_submit_rh_msg(priv, dev, pipe, buffer, len, + setup); } pid = DWC2_HC_PID_SETUP; - ret = chunk_msg(dev, pipe, &pid, 0, setup, 8, true); + ret = chunk_msg(priv, dev, pipe, &pid, 0, setup, 8, true); if (ret) return ret; if (buffer) { pid = DWC2_HC_PID_DATA1; - ret = chunk_msg(dev, pipe, &pid, usb_pipein(pipe), buffer, + ret = chunk_msg(priv, dev, pipe, &pid, usb_pipein(pipe), buffer, len, false); if (ret) return ret; @@ -891,8 +905,8 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, status_direction = 0; pid = DWC2_HC_PID_DATA1; - ret = chunk_msg(dev, pipe, &pid, status_direction, status_buffer, 0, - false); + ret = chunk_msg(priv, dev, pipe, &pid, status_direction, + priv->status_buffer, 0, false); if (ret) return ret; @@ -901,8 +915,8 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, return 0; } -int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int len, int interval) +int _submit_int_msg(struct dwc2_priv *priv, struct usb_device *dev, + unsigned long pipe, void *buffer, int len, int interval) { unsigned long timeout; int ret; @@ -915,20 +929,18 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, printf("Timeout poll on interrupt endpoint\n"); return -ETIMEDOUT; } - ret = submit_bulk_msg(dev, pipe, buffer, len); + ret = _submit_bulk_msg(priv, dev, pipe, buffer, len); if (ret != -EAGAIN) return ret; } } -/* U-Boot USB control interface */ -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +static int dwc2_init_common(struct dwc2_priv *priv) { + struct dwc2_core_regs *regs = priv->regs; uint32_t snpsid; int i, j; - root_hub_devnum = 0; - snpsid = readl(®s->gsnpsid); printf("Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff); @@ -952,18 +964,56 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) for (i = 0; i < MAX_DEVICE; i++) { for (j = 0; j < MAX_ENDPOINT; j++) - bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0; + priv->bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0; } return 0; } -int usb_lowlevel_stop(int index) +static void dwc2_uninit_common(struct dwc2_core_regs *regs) { /* Put everything in reset. */ clrsetbits_le32(®s->hprt0, DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG, DWC2_HPRT0_PRTRST); +} + +int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len, struct devrequest *setup) +{ + return _submit_control_msg(&local, dev, pipe, buffer, len, setup); +} + +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len) +{ + return _submit_bulk_msg(&local, dev, pipe, buffer, len); +} + +int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len, int interval) +{ + return _submit_int_msg(&local, dev, pipe, buffer, len, interval); +} + +/* U-Boot USB control interface */ +int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +{ + struct dwc2_priv *priv = &local; + + memset(priv, '\0', sizeof(*priv)); + priv->root_hub_devnum = 0; + priv->regs = (struct dwc2_core_regs *)CONFIG_USB_DWC2_REG_ADDR; + priv->aligned_buffer = aligned_buffer_addr; + priv->status_buffer = status_buffer_addr; + + return dwc2_init_common(priv); +} + +int usb_lowlevel_stop(int index) +{ + dwc2_uninit_common(local.regs); + return 0; }