From patchwork Mon Jul 20 13:55:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 11674025 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5A199138A for ; Mon, 20 Jul 2020 13:55:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D07020656 for ; Mon, 20 Jul 2020 13:55:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="G2UfyQJs" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726254AbgGTNzg (ORCPT ); Mon, 20 Jul 2020 09:55:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725815AbgGTNzf (ORCPT ); Mon, 20 Jul 2020 09:55:35 -0400 Received: from mail-lf1-x143.google.com (mail-lf1-x143.google.com [IPv6:2a00:1450:4864:20::143]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6ABD7C061794 for ; Mon, 20 Jul 2020 06:55:35 -0700 (PDT) Received: by mail-lf1-x143.google.com with SMTP id u25so9766013lfm.1 for ; Mon, 20 Jul 2020 06:55:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=e3+JeUl3CpBB0FycooOayrLlEsJhXD+xmMJLv8bz46A=; b=G2UfyQJsn4FUEJth9lR4XmpvuqGoH6XnERRenXS20kQg1qLd/rkzwi8feuTReY08+K vRUl1RiBK5bAdDCE7+hqsD9XwPF7bIgr4/cQkAlITY9lLqpDhDHdhlVoOs4RhwHQ5uAO NFtwFvvB+grcxlCYZhmEfNO0HYcib50qGIKYVfhjuPB5zQylI5HNpI0VxpIrG5Mm56Bd Kme5/k1aWeXS1ntblsLzChwQvKYEFvha1tGWd8XprwGouGSyNLNbL6JvYTZTAGQxZ8S8 rwmmtsTWBwaRKF1Klm4rJ109MDpxRx222eS1K/J69vTzYWLK7Q3yktHlVkGuhWUphmSq cEAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=e3+JeUl3CpBB0FycooOayrLlEsJhXD+xmMJLv8bz46A=; b=FeAoK/3efd0qEYhsvf8md+iip3kF20bM7LhluJN8F3gZXEt+PZ+1xZKwn/pzyuVCfZ LC9bo7dRsaDDV0yJ4A3XsU8JOJbwU3Y/LdEyeyzBCF55ViTWJLIs/oEtQmRvK+SCN90I ZHVjlUnnwckuPm7U1uyMGzxD2t05x/cUEXRr6MbWuTL47ehtNp/3slN0t1HN89rCc47A KNhAUAM1nZs8HezTuaj6pNg0uTRRE/Ew3ZQO/5URDqkIf3WCph5ohQXFVoZCKHHHRQIy 3zAIcaizGgwNFpRlpc9BQxwH8NjxNld8djWkh44Huc/ytpgL+N0uJem0NWROsYCIMJmv HRTg== X-Gm-Message-State: AOAM532UdxBimMAVl2dQzXSW9Uz4DRlgNWZJ5h8Mji6TexiSen0n2uv0 vEbEAW2MlhaLqmHYsewpoMyhQ05PDgQ= X-Google-Smtp-Source: ABdhPJxry2arX/0QrLFWirahYi23xci0w8mBBh3h+Cj2KYibitvBX/eXlVuI0b4MLtNlr/NLOI9UUw== X-Received: by 2002:a19:c7d0:: with SMTP id x199mr5686680lff.205.1595253333816; Mon, 20 Jul 2020 06:55:33 -0700 (PDT) Received: from genomnajs.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id b18sm648683lfp.36.2020.07.20.06.55.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Jul 2020 06:55:32 -0700 (PDT) From: Linus Walleij To: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, Linus Walleij , Janusz Krzysztofik , Tony Lindgren , Alan Stern Subject: [PATCH 1/2 v3] usb: ohci-omap: Create private state container Date: Mon, 20 Jul 2020 15:55:23 +0200 Message-Id: <20200720135524.100374-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The OMAP1 was using static locals to hold the clock handles which is uncommon and does not scale. Create a private data struct and use that to hold the clocks. Cc: Janusz Krzysztofik Cc: Tony Lindgren Acked-by: Alan Stern Signed-off-by: Linus Walleij --- ChangeLog v2->v3: - Collected Alan's ACK. ChangeLog v1->v2: - Fix up the error path to free the HCD *after* putting the stuff inside the state container. - Also fix up the remove() path similarly. - Use some reasonable names on errorpath labels we are touching or adding. - Fix a tab alignment. --- drivers/usb/host/ohci-omap.c | 85 +++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index d8d35d456456..a4bdd2b7af83 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -69,22 +69,27 @@ static inline int tps65010_set_gpio_out_value(unsigned gpio, unsigned value) #endif -static struct clk *usb_host_ck; -static struct clk *usb_dc_ck; +struct ohci_omap_priv { + struct clk *usb_host_ck; + struct clk *usb_dc_ck; +}; static const char hcd_name[] = "ohci-omap"; static struct hc_driver __read_mostly ohci_omap_hc_driver; -static void omap_ohci_clock_power(int on) +#define hcd_to_ohci_omap_priv(h) \ + ((struct ohci_omap_priv *)hcd_to_ohci(h)->priv) + +static void omap_ohci_clock_power(struct ohci_omap_priv *priv, int on) { if (on) { - clk_enable(usb_dc_ck); - clk_enable(usb_host_ck); + clk_enable(priv->usb_dc_ck); + clk_enable(priv->usb_host_ck); /* guesstimate for T5 == 1x 32K clock + APLL lock time */ udelay(100); } else { - clk_disable(usb_host_ck); - clk_disable(usb_dc_ck); + clk_disable(priv->usb_host_ck); + clk_disable(priv->usb_dc_ck); } } @@ -196,6 +201,7 @@ static int ohci_omap_reset(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = dev_get_platdata(hcd->self.controller); + struct ohci_omap_priv *priv = hcd_to_ohci_omap_priv(hcd); int need_transceiver = (config->otg != 0); int ret; @@ -235,7 +241,7 @@ static int ohci_omap_reset(struct usb_hcd *hcd) } #endif - omap_ohci_clock_power(1); + omap_ohci_clock_power(priv, 1); if (cpu_is_omap15xx()) { omap_1510_local_bus_power(1); @@ -305,6 +311,7 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev) { int retval, irq; struct usb_hcd *hcd = 0; + struct ohci_omap_priv *priv; if (pdev->num_resources != 2) { dev_err(&pdev->dev, "invalid num_resources: %i\n", @@ -318,34 +325,35 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev) return -ENODEV; } - usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck"); - if (IS_ERR(usb_host_ck)) - return PTR_ERR(usb_host_ck); + hcd = usb_create_hcd(&ohci_omap_hc_driver, &pdev->dev, + dev_name(&pdev->dev)); + if (!hcd) + return -ENOMEM; - if (!cpu_is_omap15xx()) - usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck"); - else - usb_dc_ck = clk_get(&pdev->dev, "lb_ck"); + hcd->rsrc_start = pdev->resource[0].start; + hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; + priv = hcd_to_ohci_omap_priv(hcd); - if (IS_ERR(usb_dc_ck)) { - clk_put(usb_host_ck); - return PTR_ERR(usb_dc_ck); + priv->usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck"); + if (IS_ERR(priv->usb_host_ck)) { + retval = PTR_ERR(priv->usb_host_ck); + goto err_put_hcd; } + if (!cpu_is_omap15xx()) + priv->usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck"); + else + priv->usb_dc_ck = clk_get(&pdev->dev, "lb_ck"); - hcd = usb_create_hcd(&ohci_omap_hc_driver, &pdev->dev, - dev_name(&pdev->dev)); - if (!hcd) { - retval = -ENOMEM; - goto err0; + if (IS_ERR(priv->usb_dc_ck)) { + retval = PTR_ERR(priv->usb_dc_ck); + goto err_put_host_ck; } - hcd->rsrc_start = pdev->resource[0].start; - hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); retval = -EBUSY; - goto err1; + goto err_put_dc_ck; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); @@ -370,11 +378,12 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev) iounmap(hcd->regs); err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err1: +err_put_dc_ck: + clk_put(priv->usb_dc_ck); +err_put_host_ck: + clk_put(priv->usb_host_ck); +err_put_hcd: usb_put_hcd(hcd); -err0: - clk_put(usb_dc_ck); - clk_put(usb_host_ck); return retval; } @@ -393,10 +402,11 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev) static int ohci_hcd_omap_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct ohci_omap_priv *priv = hcd_to_ohci_omap_priv(hcd); dev_dbg(hcd->self.controller, "stopping USB Controller\n"); usb_remove_hcd(hcd); - omap_ohci_clock_power(0); + omap_ohci_clock_power(priv, 0); if (!IS_ERR_OR_NULL(hcd->usb_phy)) { (void) otg_set_host(hcd->usb_phy->otg, 0); usb_put_phy(hcd->usb_phy); @@ -405,9 +415,9 @@ static int ohci_hcd_omap_remove(struct platform_device *pdev) gpio_free(9); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + clk_put(priv->usb_dc_ck); + clk_put(priv->usb_host_ck); usb_put_hcd(hcd); - clk_put(usb_dc_ck); - clk_put(usb_host_ck); return 0; } @@ -419,6 +429,7 @@ static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); + struct ohci_omap_priv *priv = hcd_to_ohci_omap_priv(hcd); bool do_wakeup = device_may_wakeup(&pdev->dev); int ret; @@ -430,7 +441,7 @@ static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message) if (ret) return ret; - omap_ohci_clock_power(0); + omap_ohci_clock_power(priv, 0); return ret; } @@ -438,12 +449,13 @@ static int ohci_omap_resume(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); + struct ohci_omap_priv *priv = hcd_to_ohci_omap_priv(hcd); if (time_before(jiffies, ohci->next_statechange)) msleep(5); ohci->next_statechange = jiffies; - omap_ohci_clock_power(1); + omap_ohci_clock_power(priv, 1); ohci_resume(hcd, false); return 0; } @@ -470,7 +482,8 @@ static struct platform_driver ohci_hcd_omap_driver = { static const struct ohci_driver_overrides omap_overrides __initconst = { .product_desc = "OMAP OHCI", - .reset = ohci_omap_reset + .reset = ohci_omap_reset, + .extra_priv_size = sizeof(struct ohci_omap_priv), }; static int __init ohci_omap_init(void) From patchwork Mon Jul 20 13:55:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 11674027 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E3978138A for ; Mon, 20 Jul 2020 13:55:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C72C92070A for ; Mon, 20 Jul 2020 13:55:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="zRqLShQG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726483AbgGTNzi (ORCPT ); Mon, 20 Jul 2020 09:55:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726389AbgGTNzh (ORCPT ); Mon, 20 Jul 2020 09:55:37 -0400 Received: from mail-lj1-x241.google.com (mail-lj1-x241.google.com [IPv6:2a00:1450:4864:20::241]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2CC83C061794 for ; Mon, 20 Jul 2020 06:55:37 -0700 (PDT) Received: by mail-lj1-x241.google.com with SMTP id e8so20365763ljb.0 for ; Mon, 20 Jul 2020 06:55:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8Vtav3s6bv1gV27kgdkFoBZQmgByayoCma4ohjXPPVI=; b=zRqLShQGHqIqoOy2y8lblcMWNCr30YtQhhhgy8Gi5D/BDshl6dwPxVlQHdyHMcjUHn kgKOs5Kox8r8+YS2BnDMTELM1D+ZGdya7ZvBlp8pRYfv0OXQhvGMYj0BqoSGfPrnmEXv BIQA+SU4uBTv7L95fSEE6mzUvMwi3C0Ayv0GLdS365SKPxjBUE4lyY6PYK7GnYWy7JCn kVa7nFFIhk2zefsR7BokKmvHoVEPtU/toqX5Ka9UCmzHw3z+EGggBWreQ09X8+RPAFNo HfvPFop/IDTP3E6N+yEwGxr8/BIUfueV5DfbAz27tJw84r/QEweCDkDIrXhsvrLMzVxU BJiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8Vtav3s6bv1gV27kgdkFoBZQmgByayoCma4ohjXPPVI=; b=SGH8hF1eQ7GZGaTlSgCS7OgSISswt9Gyhz6NmXK9vUrEGIasq+z8fLgBbUj2PW8Xv3 Y//tzmKhs8yFU+Ai6dLuQa+6BZhDtEQDsW/579LG8X68HPMT5o330habYPH2P3P9amRr 8RXjqSbDMPEnSh72aezqBueSqxCtVuM+kCTx4w2GMHrNt2Okxiw1sOiBKb/0KORu3SWM RD00p2hLNkDNNZLSebaKIIIjnsj82apP6DBwGzFgK5OG9UHcjBIfZHDVueEeJb7P1RgA +JM0yNXM4nput26DkUYWF/l5AHWYn0xVnaQNtrWF+6YIyrXiohwjQcphwVL1DYIKNI7E i5Pg== X-Gm-Message-State: AOAM532mEiDH+xXndtHSpojHyW+tyB8Jqey98YV3p1l9L2AkmHPSWXTO fio4VGj6AhCG4CKDv+LTsAMrN4PUjG8= X-Google-Smtp-Source: ABdhPJxAVVvk87KE4nG9nEvka4XvWCRx08tw8sS1TdlsNGGSiM1UJt24uSvAul8HbrxUj0y9V1OPtg== X-Received: by 2002:a2e:3316:: with SMTP id d22mr10803217ljc.18.1595253335605; Mon, 20 Jul 2020 06:55:35 -0700 (PDT) Received: from genomnajs.ideon.se ([85.235.10.227]) by smtp.gmail.com with ESMTPSA id b18sm648683lfp.36.2020.07.20.06.55.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Jul 2020 06:55:35 -0700 (PDT) From: Linus Walleij To: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, Linus Walleij , Janusz Krzysztofik , Tony Lindgren , Alan Stern Subject: [PATCH 2/2 v3] usb: ohci-omap: Convert to use GPIO descriptors Date: Mon, 20 Jul 2020 15:55:24 +0200 Message-Id: <20200720135524.100374-2-linus.walleij@linaro.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200720135524.100374-1-linus.walleij@linaro.org> References: <20200720135524.100374-1-linus.walleij@linaro.org> MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The OMAP1 OHCI driver is using the legacy GPIO API to grab some random GPIO lines. One is from the TPS65010 chip and used for power, another one is for overcurrent and while the driver picks this line it doesn't watch it at all. Convert the driver and the OMAP1 OSK board file to pass these two GPIOs as machine described GPIO descriptors. I noticed the overcurrent GPIO line is not really used in the code so dropped in a little comment for other developers. Cc: Janusz Krzysztofik Cc: Tony Lindgren Acked-by: Alan Stern Signed-off-by: Linus Walleij --- ChangeLog v2->v3: - Fix spelling error in commit message. - Add a helpful comment and TODO to the overcurrent handling. - Collected Alan's ACK. ChangeLog v1->v2: - Rebase on the changes to patch 1 - Fix up the errorpath in the same vein as in patch 1 --- arch/arm/mach-omap1/board-osk.c | 17 ++++++++++ drivers/usb/host/ohci-omap.c | 59 ++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 4df15e693b6e..144b9caa935c 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -26,6 +26,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include +#include #include #include #include @@ -55,6 +56,9 @@ #include "common.h" +/* Name of the GPIO chip used by the OMAP for GPIOs 0..15 */ +#define OMAP_GPIO_LABEL "gpio-0-15" + /* At OMAP5912 OSK the Ethernet is directly connected to CS1 */ #define OMAP_OSK_ETHR_START 0x04800300 @@ -240,7 +244,9 @@ static struct tps65010_board tps_board = { static struct i2c_board_info __initdata osk_i2c_board_info[] = { { + /* This device will get the name "i2c-tps65010" */ I2C_BOARD_INFO("tps65010", 0x48), + .dev_name = "tps65010", .platform_data = &tps_board, }, @@ -278,6 +284,16 @@ static void __init osk_init_cf(void) irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING); } +static struct gpiod_lookup_table osk_usb_gpio_table = { + .dev_id = "ohci", + .table = { + /* Power GPIO on the I2C-attached TPS65010 */ + GPIO_LOOKUP("i2c-tps65010", 1, "power", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP(OMAP_GPIO_LABEL, 9, "overcurrent", + GPIO_ACTIVE_HIGH), + }, +}; + static struct omap_usb_config osk_usb_config __initdata = { /* has usb host connector (A) ... for development it can also * be used, with a NONSTANDARD gender-bending cable/dongle, as @@ -581,6 +597,7 @@ static void __init osk_init(void) l |= (3 << 1); omap_writel(l, USB_TRANSCEIVER_CTRL); + gpiod_add_lookup_table(&osk_usb_gpio_table); omap1_usb_init(&osk_usb_config); /* irq for tps65010 chip */ diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index a4bdd2b7af83..9ccdf2c216b5 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -53,25 +53,11 @@ #define DRIVER_DESC "OHCI OMAP driver" -#ifdef CONFIG_TPS65010 -#include -#else - -#define LOW 0 -#define HIGH 1 - -#define GPIO1 1 - -static inline int tps65010_set_gpio_out_value(unsigned gpio, unsigned value) -{ - return 0; -} - -#endif - struct ohci_omap_priv { struct clk *usb_host_ck; struct clk *usb_dc_ck; + struct gpio_desc *power; + struct gpio_desc *overcurrent; }; static const char hcd_name[] = "ohci-omap"; @@ -97,22 +83,22 @@ static void omap_ohci_clock_power(struct ohci_omap_priv *priv, int on) * Board specific gang-switched transceiver power on/off. * NOTE: OSK supplies power from DC, not battery. */ -static int omap_ohci_transceiver_power(int on) +static int omap_ohci_transceiver_power(struct ohci_omap_priv *priv, int on) { if (on) { if (machine_is_omap_innovator() && cpu_is_omap1510()) __raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL) | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); - else if (machine_is_omap_osk()) - tps65010_set_gpio_out_value(GPIO1, LOW); + else if (priv->power) + gpiod_set_value(priv->power, 0); } else { if (machine_is_omap_innovator() && cpu_is_omap1510()) __raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL) & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); - else if (machine_is_omap_osk()) - tps65010_set_gpio_out_value(GPIO1, HIGH); + else if (priv->power) + gpiod_set_value(priv->power, 1); } return 0; @@ -272,8 +258,6 @@ static int ohci_omap_reset(struct usb_hcd *hcd) /* gpio9 for overcurrent detction */ omap_cfg_reg(W8_1610_GPIO9); - gpio_request(9, "OHCI overcurrent"); - gpio_direction_input(9); /* for paranoia's sake: disable USB.PUEN */ omap_cfg_reg(W4_USB_HIGHZ); @@ -287,7 +271,7 @@ static int ohci_omap_reset(struct usb_hcd *hcd) } /* FIXME hub_wq hub requests should manage power switching */ - omap_ohci_transceiver_power(1); + omap_ohci_transceiver_power(priv, 1); /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized @@ -334,6 +318,29 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev) hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; priv = hcd_to_ohci_omap_priv(hcd); + /* Obtain two optional GPIO lines */ + priv->power = devm_gpiod_get_optional(&pdev->dev, "power", GPIOD_ASIS); + if (IS_ERR(priv->power)) { + retval = PTR_ERR(priv->power); + goto err_put_hcd; + } + if (priv->power) + gpiod_set_consumer_name(priv->power, "OHCI power"); + + /* + * This "overcurrent" GPIO line isn't really used in the code, + * but has a designated hardware function. + * TODO: implement proper overcurrent handling. + */ + priv->overcurrent = devm_gpiod_get_optional(&pdev->dev, "overcurrent", + GPIOD_IN); + if (IS_ERR(priv->overcurrent)) { + retval = PTR_ERR(priv->overcurrent); + goto err_put_hcd; + } + if (priv->overcurrent) + gpiod_set_consumer_name(priv->overcurrent, "OHCI overcurrent"); + priv->usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck"); if (IS_ERR(priv->usb_host_ck)) { retval = PTR_ERR(priv->usb_host_ck); @@ -411,8 +418,6 @@ static int ohci_hcd_omap_remove(struct platform_device *pdev) (void) otg_set_host(hcd->usb_phy->otg, 0); usb_put_phy(hcd->usb_phy); } - if (machine_is_omap_osk()) - gpio_free(9); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); clk_put(priv->usb_dc_ck);