From patchwork Tue Aug 28 07:03:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Zhao X-Patchwork-Id: 1379431 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 01FA5DF283 for ; Tue, 28 Aug 2012 07:12:29 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1T6Fun-0004JE-IA; Tue, 28 Aug 2012 07:08:46 +0000 Received: from am1ehsobe006.messaging.microsoft.com ([213.199.154.209] helo=am1outboundpool.messaging.microsoft.com) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1T6Fsf-00036h-0z for linux-arm-kernel@lists.infradead.org; Tue, 28 Aug 2012 07:06:34 +0000 Received: from mail50-am1-R.bigfish.com (10.3.201.240) by AM1EHSOBE010.bigfish.com (10.3.204.30) with Microsoft SMTP Server id 14.1.225.23; Tue, 28 Aug 2012 07:06:32 +0000 Received: from mail50-am1 (localhost [127.0.0.1]) by mail50-am1-R.bigfish.com (Postfix) with ESMTP id 0971D220128; Tue, 28 Aug 2012 07:06:32 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1202hzz8275bhz2dh2a8h668h839hd24he5bhf0ah107ah1155h) Received: from mail50-am1 (localhost.localdomain [127.0.0.1]) by mail50-am1 (MessageSwitch) id 1346137590128545_8609; Tue, 28 Aug 2012 07:06:30 +0000 (UTC) Received: from AM1EHSMHS006.bigfish.com (unknown [10.3.201.254]) by mail50-am1.bigfish.com (Postfix) with ESMTP id 130623A0047; Tue, 28 Aug 2012 07:06:30 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by AM1EHSMHS006.bigfish.com (10.3.207.106) with Microsoft SMTP Server (TLS) id 14.1.225.23; Tue, 28 Aug 2012 07:06:28 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server (TLS) id 14.2.309.3; Tue, 28 Aug 2012 02:06:26 -0500 Received: from b20223-02.ap.freescale.net (b20223-02.ap.freescale.net [10.192.242.124]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id q7S72ogO032560; Tue, 28 Aug 2012 00:06:22 -0700 From: Richard Zhao To: , Subject: [PATCH v2 10/11] USB: chipidea: add set_vbus_power support Date: Tue, 28 Aug 2012 15:03:16 +0800 Message-ID: <1346137397-32374-11-git-send-email-richard.zhao@freescale.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1346137397-32374-1-git-send-email-richard.zhao@freescale.com> References: <1346137397-32374-1-git-send-email-richard.zhao@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [213.199.154.209 listed in list.dnswl.org] 0.0 KHOP_BIG_TO_CC Sent to 10+ recipients instaed of Bcc or a list -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: marex@denx.de, B20596@freescale.com, dong.aisheng@linaro.org, fabio.estevam@freescale.com, alexander.shishkin@linux.intel.com, B29397@freescale.com, balbi@ti.com, stern@rowland.harvard.edu, kernel@pengutronix.de, gregkh@linuxfoundation.org, richard.zhao@freescale.com, shawn.guo@linaro.org, mkl@pengutronix.de, linuxzsc@gmail.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org set_vbus_power is used to enable or disable vbus power for usb host. [Marc Kleine-Budde : fix regulator unbalance disable] Signed-off-by: Richard Zhao --- drivers/usb/chipidea/ci13xxx_imx.c | 44 +++++++++++++++++++++--------------- drivers/usb/chipidea/host.c | 8 +++++++ include/linux/usb/chipidea.h | 2 ++ 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 0f5ca4b..5c0be08 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -27,6 +27,8 @@ #define pdev_to_phy(pdev) \ ((struct usb_phy *)platform_get_drvdata(pdev)) +#define ci_to_imx_data(ci) \ + ((struct ci13xxx_imx_data *)dev_get_drvdata(ci->dev->parent)) struct ci13xxx_imx_data { struct device_node *phy_np; @@ -85,12 +87,32 @@ EXPORT_SYMBOL_GPL(usbmisc_get_init_data); /* End of common functions shared by usbmisc drivers*/ +static int ci13xxx_imx_vbus(struct ci13xxx *ci, int enable) +{ + struct ci13xxx_imx_data *data = ci_to_imx_data(ci); + int ret; + + if (!data->reg_vbus) + return 0; + + if (enable) + ret = regulator_enable(data->reg_vbus); + else + ret = regulator_disable(data->reg_vbus); + if (ret) + dev_err(ci->dev, "ci13xxx_imx_vbus failed, enable:%d err:%d\n", + enable, ret); + + return ret; +} + static struct ci13xxx_platform_data ci13xxx_imx_platdata __devinitdata = { .name = "ci13xxx_imx", .flags = CI13XXX_REQUIRE_TRANSCEIVER | CI13XXX_PULLUP_ON_VBUS | CI13XXX_DISABLE_STREAMING, .capoffset = DEF_CAPOFFSET, + .set_vbus_power = ci13xxx_imx_vbus, }; static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) @@ -153,20 +175,11 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) } } - /* we only support host now, so enable vbus here */ reg_vbus = devm_regulator_get(&pdev->dev, "vbus"); - if (!IS_ERR(reg_vbus)) { - ret = regulator_enable(reg_vbus); - if (ret) { - dev_err(&pdev->dev, - "Failed to enable vbus regulator, err=%d\n", - ret); - goto put_np; - } + if (!IS_ERR(reg_vbus)) data->reg_vbus = reg_vbus; - } else { + else reg_vbus = NULL; - } ci13xxx_imx_platdata.phy = data->phy; @@ -191,6 +204,8 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) } } + platform_set_drvdata(pdev, data); + plat_ci = ci13xxx_add_device(&pdev->dev, pdev->resource, pdev->num_resources, &ci13xxx_imx_platdata); @@ -203,7 +218,6 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) } data->ci_pdev = plat_ci; - platform_set_drvdata(pdev, data); pm_runtime_no_callbacks(&pdev->dev); pm_runtime_enable(&pdev->dev); @@ -211,9 +225,6 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) return 0; err: - if (reg_vbus) - regulator_disable(reg_vbus); -put_np: if (phy_np) of_node_put(phy_np); clk_disable_unprepare(data->clk); @@ -227,9 +238,6 @@ static int __devexit ci13xxx_imx_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); ci13xxx_remove_device(data->ci_pdev); - if (data->reg_vbus) - regulator_disable(data->reg_vbus); - if (data->phy) { usb_phy_shutdown(data->phy); module_put(data->phy->dev->driver->owner); diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index ebff9f4..e091147 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -106,6 +106,12 @@ static int host_start(struct ci13xxx *ci) if (usb_disabled()) return -ENODEV; + if (ci->platdata->set_vbus_power) { + ret = ci->platdata->set_vbus_power(ci, 1); + if (ret) + return ret; + } + hcd = usb_create_hcd(&ci_ehci_hc_driver, ci->dev, dev_name(ci->dev)); if (!hcd) return -ENOMEM; @@ -138,6 +144,8 @@ static void host_stop(struct ci13xxx *ci) usb_remove_hcd(hcd); usb_put_hcd(hcd); + if (ci->platdata->set_vbus_power) + ci->platdata->set_vbus_power(ci, 0); } int ci_hdrc_host_init(struct ci13xxx *ci) diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 544825d..080f479 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -23,6 +23,8 @@ struct ci13xxx_platform_data { #define CI13XXX_CONTROLLER_RESET_EVENT 0 #define CI13XXX_CONTROLLER_STOPPED_EVENT 1 void (*notify_event) (struct ci13xxx *ci, unsigned event); + /* set vbus power, it must be called in non-atomic context */ + int (*set_vbus_power) (struct ci13xxx *ci, int enable); }; /* Default offset of capability registers */