From patchwork Thu Jul 7 22:21:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 71633 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp126570qgy; Thu, 7 Jul 2016 15:23:19 -0700 (PDT) X-Received: by 10.67.3.7 with SMTP id bs7mr4284225pad.86.1467930196318; Thu, 07 Jul 2016 15:23:16 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z14si3894846pfj.116.2016.07.07.15.23.16; Thu, 07 Jul 2016 15:23:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932393AbcGGWXD (ORCPT + 30 others); Thu, 7 Jul 2016 18:23:03 -0400 Received: from mail-pa0-f47.google.com ([209.85.220.47]:35124 "EHLO mail-pa0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753471AbcGGWVx (ORCPT ); Thu, 7 Jul 2016 18:21:53 -0400 Received: by mail-pa0-f47.google.com with SMTP id dx3so9523677pab.2 for ; Thu, 07 Jul 2016 15:21:52 -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; bh=rlZZaaSGMJCqtP2qk6Jv1E69JePT6xpZgml2WJJ6NYI=; b=VHcZb/3mFenmKKpI62jG9ToFi7Hfv38MGKxswtJNXz3/wOBy2+gB4t//9+Ucj1tRc6 6E1URAXAaXYWSao9LEqJRUovnO5w04K1VO10aO1aO2tGBUSiqhMmdnVqRBKC8InA874T c6uZ0hossPTWVK2YH4w5dEV2VV4+Ta5B0boHw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rlZZaaSGMJCqtP2qk6Jv1E69JePT6xpZgml2WJJ6NYI=; b=Y49b9bzeCWt1VndU10Lx0IvB1w30de3s+1mWDSHP3TnaplGaKMxeh0dvPbb9ou5eBO J3uD8b6bPva2Oabn0+q/TjjasZ9kzPwHBEpOXGdeQEdSxryxBw2DbeOHnMN3mnuaoftp nhGqM4FE39wWVIgJaWsPeblfpdOsZEiVUB25g51FicTLwhrJmONgFxdiJ8BMrCDMa0Yd 4qCm8416492vQ4Cynw+yvVO6wNOWiNu31U2cT3YOcpbFZ7MagO1Ks7+Vg+lX/yYH8DIu J0eh7nmp6SvdcKhaHUk4SRrbe/Xn4070DnTJVW3/PGUaGwqmYYOaBA5ot6mvp7BEgndv aeLQ== X-Gm-Message-State: ALyK8tKK0PKPRg/Jxt1B8sOza2Tg6Ara5gFun1UzMlnOyLh7eJBvF/TrU/VOUy4f9qS9pupF X-Received: by 10.66.254.102 with SMTP id ah6mr4274670pad.59.1467930105698; Thu, 07 Jul 2016 15:21:45 -0700 (PDT) Received: from localhost.localdomain (ip68-101-172-78.sd.sd.cox.net. [68.101.172.78]) by smtp.gmail.com with ESMTPSA id j8sm6781807paj.22.2016.07.07.15.21.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 07 Jul 2016 15:21:45 -0700 (PDT) From: Stephen Boyd To: linux-usb@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Andy Gross , Bjorn Andersson , Neil Armstrong , Arnd Bergmann , Felipe Balbi , Peter Chen , Greg Kroah-Hartman Subject: [PATCH v2 18/22] usb: chipidea: msm: Add reset controller for PHY POR bit Date: Thu, 7 Jul 2016 15:21:09 -0700 Message-Id: <20160707222114.1673-19-stephen.boyd@linaro.org> X-Mailer: git-send-email 2.9.0.rc2.8.ga28705d In-Reply-To: <20160707222114.1673-1-stephen.boyd@linaro.org> References: <20160707222114.1673-1-stephen.boyd@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The MSM chipidea wrapper has two bits that are used to reset the first or second phy. Add support for these bits via the reset controller framework, so that phy drivers can reset their hardware at the right time during initialization. Cc: Peter Chen Cc: Greg Kroah-Hartman Signed-off-by: Stephen Boyd --- drivers/usb/chipidea/Kconfig | 1 + drivers/usb/chipidea/ci_hdrc_msm.c | 45 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) -- 2.9.0.rc2.8.ga28705d diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index 4f8c342a8865..488ecdf56bdd 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -2,6 +2,7 @@ config USB_CHIPIDEA tristate "ChipIdea Highspeed Dual Role Controller" depends on ((USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET)) && HAS_DMA select EXTCON + select RESET_CONTROLLER help Say Y here if your system has a dual role high speed USB controller based on ChipIdea silicon IP. Currently, only the diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index da2d399acdd2..ab6a7713ee5c 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -31,8 +32,10 @@ #define HSPHY_SESS_VLD_CTRL BIT(25) /* Vendor base starts at 0x200 beyond CI base */ +#define HS_PHY_CTRL 0x0040 #define HS_PHY_SEC_CTRL 0x0078 #define HS_PHY_DIG_CLAMP_N BIT(16) +#define HS_PHY_POR_ASSERT BIT(0) struct ci_hdrc_msm { struct platform_device *ci; @@ -40,11 +43,38 @@ struct ci_hdrc_msm { struct clk *iface_clk; struct clk *fs_clk; struct ci_hdrc_platform_data pdata; + struct reset_controller_dev rcdev; bool secondary_phy; bool hsic; void __iomem *base; }; +static int +ci_hdrc_msm_por_reset(struct reset_controller_dev *r, unsigned long id) +{ + struct ci_hdrc_msm *ci_msm = container_of(r, struct ci_hdrc_msm, rcdev); + void __iomem *addr = ci_msm->base; + u32 val; + + if (id) + addr += HS_PHY_SEC_CTRL; + else + addr += HS_PHY_CTRL; + + val = readl_relaxed(addr); + val |= HS_PHY_POR_ASSERT; + writel(val, addr); + udelay(12); + val &= ~HS_PHY_POR_ASSERT; + writel(val, addr); + + return 0; +} + +static const struct reset_control_ops ci_hdrc_msm_reset_ops = { + .reset = ci_hdrc_msm_por_reset, +}; + static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) { struct device *dev = ci->dev->parent; @@ -186,10 +216,18 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (!ci->base) return -ENOMEM; - ret = clk_prepare_enable(ci->fs_clk); + ci->rcdev.owner = THIS_MODULE; + ci->rcdev.ops = &ci_hdrc_msm_reset_ops; + ci->rcdev.of_node = pdev->dev.of_node; + ci->rcdev.nr_resets = 2; + ret = reset_controller_register(&ci->rcdev); if (ret) return ret; + ret = clk_prepare_enable(ci->fs_clk); + if (ret) + goto err_fs; + reset_control_assert(reset); usleep_range(10000, 12000); reset_control_deassert(reset); @@ -198,7 +236,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) ret = clk_prepare_enable(ci->core_clk); if (ret) - return ret; + goto err_fs; ret = clk_prepare_enable(ci->iface_clk); if (ret) @@ -236,6 +274,8 @@ err_mux: clk_disable_unprepare(ci->iface_clk); err_iface: clk_disable_unprepare(ci->core_clk); +err_fs: + reset_controller_unregister(&ci->rcdev); return ret; } @@ -247,6 +287,7 @@ static int ci_hdrc_msm_remove(struct platform_device *pdev) ci_hdrc_remove_device(ci->ci); clk_disable_unprepare(ci->iface_clk); clk_disable_unprepare(ci->core_clk); + reset_controller_unregister(&ci->rcdev); return 0; }