From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752715AbbDBIHH (ORCPT ); Thu, 2 Apr 2015 04:07:07 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:30915 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752522AbbDBIGg (ORCPT ); Thu, 2 Apr 2015 04:06:36 -0400 X-AuditID: cbfec7f4-b7f126d000001e9a-a6-551cf7dca010 From: Krzysztof Kozlowski To: Kukjin Kim , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Javier Martinez Canillas , Marek Szyprowski , Krzysztof Kozlowski Subject: [PATCH 1/2] ARM: EXYNOS: Get current parent clock for power domain on/off Date: Thu, 02 Apr 2015 10:06:18 +0200 Message-id: <1427961979-29477-1-git-send-email-k.kozlowski@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrAJMWRmVeSWpSXmKPExsVy+t/xa7p3vsuEGhw5JmEx/8g5Voujvwss Xr8wtOh//JrZYtPja6wWl3fNYbOYcX4fk8XaI3fZHTg8/j6/zuKxaVUnm8fmJfUefVtWMXp8 3iQXwBrFZZOSmpNZllqkb5fAlXHn02T2gp0SFT/WTGZvYPwk3MXIySEhYCIx6etEdghbTOLC vfVsXYxcHEICSxkl1k75yQrh9DFJdM86xAxSxSZgLLF5+RI2EFtEYAWjxMUmS5AiZoF5jBLH /iwASwgLhEjsntXF2MXIwcEioCrx460gSJhXwF3i6owLzBDb5CROHpvMOoGRewEjwypG0dTS 5ILipPRcQ73ixNzi0rx0veT83E2MkFD5soNx8TGrQ4wCHIxKPLw3PkmHCrEmlhVX5h5ilOBg VhLhzb8nEyrEm5JYWZValB9fVJqTWnyIkYmDU6qBceva8OfTAwqmHrXo4tZ8lt3D0bOLJaNx qXvI9RjWhE0L1iUf8otbzRx/qLLzguuvuFVSqXZTfmS51eTycViXZ/avlYuVWK9y++zmrwHv 32Q0q6QUnn0cM9FbxrT0QdmN7Vdyj12rX87+O2jDvHiH/rSrO9/kHhFPNHI1ai8zSvKc1F4u 1xKtxFKckWioxVxUnAgAd2Mg6fMBAAA= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Using a fixed (by DTS) parent for clocks when turning on the power domain may introduce issues in other drivers. For example when such driver changes the parent during runtime and expects that he is the only place of such change. Do not rely entirely on DTS providing the fixed parent for such clocks. Instead if "pclkN" clock name is missing, grab a current parent of clock with clk_get_parent(). Signed-off-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/arm/exynos/power_domain.txt | 8 +++++--- arch/arm/mach-exynos/pm_domains.c | 9 ++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt index 5da38c5ed476..0fc1312f6fd5 100644 --- a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt +++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt @@ -19,9 +19,11 @@ Optional Properties: domains. - clock-names: The following clocks can be specified: - oscclk: Oscillator clock. - - pclkN, clkN: Pairs of parent of input clock and input clock to the - devices in this power domain. Maximum of 4 pairs (N = 0 to 3) - are supported currently. + - pclkN, clkN: Input clocks (clkN) to the devices in this power domain. + Optionally with parrents (pclkN). If such parent is provided + it will be used for reparenting the given clock when domain + is turned on. Otherwise the parent before power down will be + used. Maximum of 4 pairs (N = 0 to 3) are supported currently. - asbN: Clocks required by asynchronous bridges (ASB) present in the power domain. These clock should be enabled during power domain on/off operations. diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index cbe56b35aea0..c55bcf52a6ad 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -37,6 +37,7 @@ struct exynos_pm_domain { struct clk *oscclk; struct clk *clk[MAX_CLK_PER_DOMAIN]; struct clk *pclk[MAX_CLK_PER_DOMAIN]; + unsigned int pclk_dynamic:MAX_CLK_PER_DOMAIN; struct clk *asb_clk[MAX_CLK_PER_DOMAIN]; }; @@ -62,6 +63,9 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { if (IS_ERR(pd->clk[i])) break; + /* If parent was not set in DT, save current parent */ + if (pd->pclk_dynamic & (1 << i)) + pd->pclk[i] = clk_get_parent(pd->clk[i]); if (clk_set_parent(pd->clk[i], pd->oscclk)) pr_err("%s: error setting oscclk as parent to clock %d\n", pd->name, i); @@ -164,9 +168,8 @@ static __init int exynos4_pm_init_power_domain(void) snprintf(clk_name, sizeof(clk_name), "pclk%d", i); pd->pclk[i] = clk_get(dev, clk_name); if (IS_ERR(pd->pclk[i])) { - clk_put(pd->clk[i]); - pd->clk[i] = ERR_PTR(-EINVAL); - break; + pd->pclk_dynamic |= (1 << i); + pd->pclk[i] = clk_get_parent(pd->clk[i]); } } -- 1.9.1