mirror of https://gitee.com/openkylin/linux.git
Samsung soc drivers changes for v4.18
1. Clock operations during power domain on/off were moved to respective clock driver so clean up obsolete code from power domain driver. -----BEGIN PGP SIGNATURE----- iQItBAABCAAXBQJa+FuREBxrcnprQGtlcm5lbC5vcmcACgkQwTdm5oaLg9dzlw// ZwGzvmLaH2IPhRuLRGahdW2rw5roEYJTfMqrPAgTkRIiEMHNMa8cdVQtiA3sF+gr aez5JZV5pEkkRbPFvygL5oFY8j+DfbBxzLMOEAcjzROfNVXQn7A+UeKWT4jFB25E Mvc88GD3P9lbQGEIPmb/Pthqf4qYOOBwaTGfJAxhqaw7pTtg/Nke8jtuW0M2mwKK bbhBzZuJrLKGd+wXK/ANnMJPJPq37f3In4y72h+Re6Ux64ifb5iy7fSyUUdsAKWK 9zFv/gYE+/9XNpDXA14nuxqDxWVkKmck4QF5W/ePCsyDAmsdyvF60iWoKtWuBJ+U aTFHQqyM7e4eCFeXVCm4XDZtYvNRyKAiXQQEwXYN5viaGw2xL48woaV0Yon5+Nw0 2U+NuLKWG1QB+bo+pWCgTAmiTiv7tgII0US2HijbGbPaCo1KIkafgCASmjPJydQH x5lEFnFbxHzV02bj6z4931FkVEUU0b6Y0ANwaPBnjNDcPAhBE9hqkK9PxrW5rBfQ ioAh6AEwixu3b04dkn1ZIJVnnkjDsLGupHBnKzxSfwCkCuRsM6vbHDxM7OWOdf7y vLA4VLxWfQ4cXUy5dZ5Yp/Hnta+A3ZaJ2ftYhbsgProjEuE8dkKyX+NY10HK+O8U qzvJ13dr1/g/hLwL6FsR9bp+4sBSFilElMDhJ9gijc4= =buKl -----END PGP SIGNATURE----- Merge tag 'samsung-drivers-4.18' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into next/drivers Samsung soc drivers changes for v4.18 1. Clock operations during power domain on/off were moved to respective clock driver so clean up obsolete code from power domain driver. * tag 'samsung-drivers-4.18' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux: soc: samsung: pm_domains: Deprecate support for clocks Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
3ea8f233cf
|
@ -15,23 +15,13 @@ Required Properties:
|
||||||
Optional Properties:
|
Optional Properties:
|
||||||
- label: Human readable string with domain name. Will be visible in userspace
|
- label: Human readable string with domain name. Will be visible in userspace
|
||||||
to let user to distinguish between multiple domains in SoC.
|
to let user to distinguish between multiple domains in SoC.
|
||||||
- clocks: List of clock handles. The parent clocks of the input clocks to the
|
|
||||||
devices in this power domain are set to oscclk before power gating
|
|
||||||
and restored back after powering on a domain. This is required for
|
|
||||||
all domains which are powered on and off and not required for unused
|
|
||||||
domains.
|
|
||||||
- clock-names: The following clocks can be specified:
|
|
||||||
- oscclk: Oscillator clock.
|
|
||||||
- clkN: Input clocks to the devices in this power domain. These clocks
|
|
||||||
will be reparented to oscclk before switching power domain off.
|
|
||||||
Their original parent will be brought back after turning on
|
|
||||||
the domain. Maximum of 4 clocks (N = 0 to 3) are supported.
|
|
||||||
- asbN: Clocks required by asynchronous bridges (ASB) present in
|
|
||||||
the power domain. These clock should be enabled during power
|
|
||||||
domain on/off operations.
|
|
||||||
- power-domains: phandle pointing to the parent power domain, for more details
|
- power-domains: phandle pointing to the parent power domain, for more details
|
||||||
see Documentation/devicetree/bindings/power/power_domain.txt
|
see Documentation/devicetree/bindings/power/power_domain.txt
|
||||||
|
|
||||||
|
Deprecated Properties:
|
||||||
|
- clocks
|
||||||
|
- clock-names
|
||||||
|
|
||||||
Node of a device using power domains must have a power-domains property
|
Node of a device using power domains must have a power-domains property
|
||||||
defined with a phandle to respective power domain.
|
defined with a phandle to respective power domain.
|
||||||
|
|
||||||
|
@ -47,8 +37,6 @@ Example:
|
||||||
mfc_pd: power-domain@10044060 {
|
mfc_pd: power-domain@10044060 {
|
||||||
compatible = "samsung,exynos4210-pd";
|
compatible = "samsung,exynos4210-pd";
|
||||||
reg = <0x10044060 0x20>;
|
reg = <0x10044060 0x20>;
|
||||||
clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_USER_ACLK333>;
|
|
||||||
clock-names = "oscclk", "clk0";
|
|
||||||
#power-domain-cells = <0>;
|
#power-domain-cells = <0>;
|
||||||
label = "MFC";
|
label = "MFC";
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,14 +13,11 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/pm_domain.h>
|
#include <linux/pm_domain.h>
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#define MAX_CLK_PER_DOMAIN 4
|
|
||||||
|
|
||||||
struct exynos_pm_domain_config {
|
struct exynos_pm_domain_config {
|
||||||
/* Value for LOCAL_PWR_CFG and STATUS fields for each domain */
|
/* Value for LOCAL_PWR_CFG and STATUS fields for each domain */
|
||||||
u32 local_pwr_cfg;
|
u32 local_pwr_cfg;
|
||||||
|
@ -33,10 +30,6 @@ struct exynos_pm_domain {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
bool is_off;
|
bool is_off;
|
||||||
struct generic_pm_domain pd;
|
struct generic_pm_domain pd;
|
||||||
struct clk *oscclk;
|
|
||||||
struct clk *clk[MAX_CLK_PER_DOMAIN];
|
|
||||||
struct clk *pclk[MAX_CLK_PER_DOMAIN];
|
|
||||||
struct clk *asb_clk[MAX_CLK_PER_DOMAIN];
|
|
||||||
u32 local_pwr_cfg;
|
u32 local_pwr_cfg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,29 +39,10 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
u32 timeout, pwr;
|
u32 timeout, pwr;
|
||||||
char *op;
|
char *op;
|
||||||
int i;
|
|
||||||
|
|
||||||
pd = container_of(domain, struct exynos_pm_domain, pd);
|
pd = container_of(domain, struct exynos_pm_domain, pd);
|
||||||
base = pd->base;
|
base = pd->base;
|
||||||
|
|
||||||
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
|
|
||||||
if (IS_ERR(pd->asb_clk[i]))
|
|
||||||
break;
|
|
||||||
clk_prepare_enable(pd->asb_clk[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set oscclk before powering off a domain*/
|
|
||||||
if (!power_on) {
|
|
||||||
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
|
|
||||||
if (IS_ERR(pd->clk[i]))
|
|
||||||
break;
|
|
||||||
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",
|
|
||||||
domain->name, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pwr = power_on ? pd->local_pwr_cfg : 0;
|
pwr = power_on ? pd->local_pwr_cfg : 0;
|
||||||
writel_relaxed(pwr, base);
|
writel_relaxed(pwr, base);
|
||||||
|
|
||||||
|
@ -86,26 +60,6 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
|
||||||
usleep_range(80, 100);
|
usleep_range(80, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore clocks after powering on a domain*/
|
|
||||||
if (power_on) {
|
|
||||||
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
|
|
||||||
if (IS_ERR(pd->clk[i]))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (IS_ERR(pd->pclk[i]))
|
|
||||||
continue; /* Skip on first power up */
|
|
||||||
if (clk_set_parent(pd->clk[i], pd->pclk[i]))
|
|
||||||
pr_err("%s: error setting parent to clock%d\n",
|
|
||||||
domain->name, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
|
|
||||||
if (IS_ERR(pd->asb_clk[i]))
|
|
||||||
break;
|
|
||||||
clk_disable_unprepare(pd->asb_clk[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,12 +101,6 @@ static __init const char *exynos_get_domain_name(struct device_node *node)
|
||||||
return kstrdup_const(name, GFP_KERNEL);
|
return kstrdup_const(name, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *soc_force_no_clk[] = {
|
|
||||||
"samsung,exynos5250-clock",
|
|
||||||
"samsung,exynos5420-clock",
|
|
||||||
"samsung,exynos5800-clock",
|
|
||||||
};
|
|
||||||
|
|
||||||
static __init int exynos4_pm_init_power_domain(void)
|
static __init int exynos4_pm_init_power_domain(void)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
|
@ -161,7 +109,7 @@ static __init int exynos4_pm_init_power_domain(void)
|
||||||
for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) {
|
for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) {
|
||||||
const struct exynos_pm_domain_config *pm_domain_cfg;
|
const struct exynos_pm_domain_config *pm_domain_cfg;
|
||||||
struct exynos_pm_domain *pd;
|
struct exynos_pm_domain *pd;
|
||||||
int on, i;
|
int on;
|
||||||
|
|
||||||
pm_domain_cfg = match->data;
|
pm_domain_cfg = match->data;
|
||||||
|
|
||||||
|
@ -189,42 +137,6 @@ static __init int exynos4_pm_init_power_domain(void)
|
||||||
pd->pd.power_on = exynos_pd_power_on;
|
pd->pd.power_on = exynos_pd_power_on;
|
||||||
pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg;
|
pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(soc_force_no_clk); i++)
|
|
||||||
if (of_find_compatible_node(NULL, NULL,
|
|
||||||
soc_force_no_clk[i]))
|
|
||||||
goto no_clk;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
|
|
||||||
char clk_name[8];
|
|
||||||
|
|
||||||
snprintf(clk_name, sizeof(clk_name), "asb%d", i);
|
|
||||||
pd->asb_clk[i] = of_clk_get_by_name(np, clk_name);
|
|
||||||
if (IS_ERR(pd->asb_clk[i]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pd->oscclk = of_clk_get_by_name(np, "oscclk");
|
|
||||||
if (IS_ERR(pd->oscclk))
|
|
||||||
goto no_clk;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
|
|
||||||
char clk_name[8];
|
|
||||||
|
|
||||||
snprintf(clk_name, sizeof(clk_name), "clk%d", i);
|
|
||||||
pd->clk[i] = of_clk_get_by_name(np, clk_name);
|
|
||||||
if (IS_ERR(pd->clk[i]))
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
* Skip setting parent on first power up.
|
|
||||||
* The parent at this time may not be useful at all.
|
|
||||||
*/
|
|
||||||
pd->pclk[i] = ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ERR(pd->clk[0]))
|
|
||||||
clk_put(pd->oscclk);
|
|
||||||
|
|
||||||
no_clk:
|
|
||||||
on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg;
|
on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg;
|
||||||
|
|
||||||
pm_genpd_init(&pd->pd, NULL, !on);
|
pm_genpd_init(&pd->pd, NULL, !on);
|
||||||
|
|
Loading…
Reference in New Issue