From patchwork Mon Jan 12 10:57:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris BREZILLON X-Patchwork-Id: 5609541 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A8EA19F2ED for ; Mon, 12 Jan 2015 11:01:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BE14320646 for ; Mon, 12 Jan 2015 11:01:40 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DFFEE205D3 for ; Mon, 12 Jan 2015 11:01:39 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YAciU-0006Hd-1k; Mon, 12 Jan 2015 10:59:26 +0000 Received: from down.free-electrons.com ([37.187.137.238] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YAchU-0005qN-QN for linux-arm-kernel@lists.infradead.org; Mon, 12 Jan 2015 10:58:27 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id 875ED847; Mon, 12 Jan 2015 11:58:11 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id A12A9845; Mon, 12 Jan 2015 11:58:10 +0100 (CET) From: Boris Brezillon To: Felipe Balbi , Greg Kroah-Hartman , linux-usb@vger.kernel.org, Nicolas Ferre , Jean-Christophe Plagniol-Villard , Alexandre Belloni Subject: [PATCH v3 2/5] usb: atmel_usba_udc: Add at91sam9g45 and at91sam9x5 errata handling Date: Mon, 12 Jan 2015 11:57:55 +0100 Message-Id: <1421060278-27329-3-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1421060278-27329-1-git-send-email-boris.brezillon@free-electrons.com> References: <1421060278-27329-1-git-send-email-boris.brezillon@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150112_025825_233751_AA1F1159 X-CRM114-Status: GOOD ( 11.69 ) X-Spam-Score: 1.0 (+) Cc: Boris Brezillon , David Laight , Sergei Shtylyov , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP at91sam9g45 and at91sam9x5 SoCs have an hardware bug forcing us to generate a pulse on the BIAS signal on "USB end of reset" and "USB end of resume" events. Reported-by: Patrice VILCHEZ Signed-off-by: Boris Brezillon Acked-by: Alexandre Belloni --- drivers/usb/gadget/udc/atmel_usba_udc.c | 28 +++++++++++++++++++++++++++- drivers/usb/gadget/udc/atmel_usba_udc.h | 2 ++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 36fd34b..55c8dde 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -331,6 +331,17 @@ static void toggle_bias(struct usba_udc *udc, int is_on) udc->errata->toggle_bias(udc, is_on); } +static void generate_bias_pulse(struct usba_udc *udc) +{ + if (!udc->bias_pulse_needed) + return; + + if (udc->errata && udc->errata->pulse_bias) + udc->errata->pulse_bias(udc); + + udc->bias_pulse_needed = false; +} + static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req) { unsigned int transaction_len; @@ -1607,6 +1618,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) if (status & USBA_DET_SUSPEND) { toggle_bias(udc, 0); usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); + udc->bias_pulse_needed = true; DBG(DBG_BUS, "Suspend detected\n"); if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver && udc->driver->suspend) { @@ -1624,6 +1636,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) if (status & USBA_END_OF_RESUME) { usba_writel(udc, INT_CLR, USBA_END_OF_RESUME); + generate_bias_pulse(udc); DBG(DBG_BUS, "Resume detected\n"); if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver && udc->driver->resume) { @@ -1659,6 +1672,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) struct usba_ep *ep0; usba_writel(udc, INT_CLR, USBA_END_OF_RESET); + generate_bias_pulse(udc); reset_all_endpoints(udc); if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver) { @@ -1818,13 +1832,25 @@ static void at91sam9rl_toggle_bias(struct usba_udc *udc, int is_on) at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); } +static void at91sam9g45_pulse_bias(struct usba_udc *udc) +{ + unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); + + at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); + at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); +} + static const struct usba_udc_errata at91sam9rl_errata = { .toggle_bias = at91sam9rl_toggle_bias, }; +static const struct usba_udc_errata at91sam9g45_errata = { + .pulse_bias = at91sam9g45_pulse_bias, +}; + static const struct of_device_id atmel_udc_dt_ids[] = { { .compatible = "atmel,at91sam9rl-udc", .data = &at91sam9rl_errata }, - { .compatible = "atmel,at91sam9g45-udc" }, + { .compatible = "atmel,at91sam9g45-udc", .data = &at91sam9g45_errata }, { .compatible = "atmel,sama5d3-udc" }, { /* sentinel */ } }; diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h index 456899e..72b3537 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.h +++ b/drivers/usb/gadget/udc/atmel_usba_udc.h @@ -306,6 +306,7 @@ struct usba_request { struct usba_udc_errata { void (*toggle_bias)(struct usba_udc *udc, int is_on); + void (*pulse_bias)(struct usba_udc *udc); }; struct usba_udc { @@ -326,6 +327,7 @@ struct usba_udc { struct clk *pclk; struct clk *hclk; struct usba_ep *usba_ep; + bool bias_pulse_needed; u16 devstatus;