From 79bb17ce8edb3141339b5882e372d0ec7346217c Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Fri, 23 Dec 2016 11:47:52 +0800 Subject: soc: rockchip: power-domain: Support domain control in hiword-registers New Rockchips SoCs may have their power-domain control in registers using a writemask-based access scheme (upper 16bit being the write mask). So add a DOMAIN_M type and handle this case accordingly. Signed-off-by: Elaine Zhang Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 1c78c42416c69..f81cdb19f88e7 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -29,6 +29,8 @@ struct rockchip_domain_info { int idle_mask; int ack_mask; bool active_wakeup; + int pwr_w_mask; + int req_w_mask; }; struct rockchip_pmu_info { @@ -87,6 +89,18 @@ struct rockchip_pmu { .active_wakeup = wakeup, \ } +#define DOMAIN_M(pwr, status, req, idle, ack, wakeup) \ +{ \ + .pwr_w_mask = (pwr >= 0) ? BIT(pwr + 16) : 0, \ + .pwr_mask = (pwr >= 0) ? BIT(pwr) : 0, \ + .status_mask = (status >= 0) ? BIT(status) : 0, \ + .req_w_mask = (req >= 0) ? BIT(req + 16) : 0, \ + .req_mask = (req >= 0) ? BIT(req) : 0, \ + .idle_mask = (idle >= 0) ? BIT(idle) : 0, \ + .ack_mask = (ack >= 0) ? BIT(ack) : 0, \ + .active_wakeup = wakeup, \ +} + #define DOMAIN_RK3288(pwr, status, req, wakeup) \ DOMAIN(pwr, status, req, req, (req) + 16, wakeup) @@ -127,9 +141,13 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd, if (pd_info->req_mask == 0) return 0; - - regmap_update_bits(pmu->regmap, pmu->info->req_offset, - pd_info->req_mask, idle ? -1U : 0); + else if (pd_info->req_w_mask) + regmap_write(pmu->regmap, pmu->info->req_offset, + idle ? (pd_info->req_mask | pd_info->req_w_mask) : + pd_info->req_w_mask); + else + regmap_update_bits(pmu->regmap, pmu->info->req_offset, + pd_info->req_mask, idle ? -1U : 0); dsb(sy); @@ -230,9 +248,13 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, if (pd->info->pwr_mask == 0) return; - - regmap_update_bits(pmu->regmap, pmu->info->pwr_offset, - pd->info->pwr_mask, on ? 0 : -1U); + else if (pd->info->pwr_w_mask) + regmap_write(pmu->regmap, pmu->info->pwr_offset, + on ? pd->info->pwr_mask : + (pd->info->pwr_mask | pd->info->pwr_w_mask)); + else + regmap_update_bits(pmu->regmap, pmu->info->pwr_offset, + pd->info->pwr_mask, on ? 0 : -1U); dsb(sy); -- cgit v1.2.3 From e9284603d857c3bf9e0c598251cd9370b7227550 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Fri, 23 Dec 2016 11:47:52 +0800 Subject: soc: rockchip: power-domain: add power domain support for rk3328 The rk3328 uses the newly introduced support for power-domain control in hiword-mask registers. Signed-off-by: Elaine Zhang Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index f81cdb19f88e7..796c46a6cbe70 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -104,6 +105,9 @@ struct rockchip_pmu { #define DOMAIN_RK3288(pwr, status, req, wakeup) \ DOMAIN(pwr, status, req, req, (req) + 16, wakeup) +#define DOMAIN_RK3328(pwr, status, req, wakeup) \ + DOMAIN_M(pwr, pwr, req, (req) + 10, req, wakeup) + #define DOMAIN_RK3368(pwr, status, req, wakeup) \ DOMAIN(pwr, status, req, (req) + 16, req, wakeup) @@ -714,6 +718,18 @@ static const struct rockchip_domain_info rk3288_pm_domains[] = { [RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2, false), }; +static const struct rockchip_domain_info rk3328_pm_domains[] = { + [RK3328_PD_CORE] = DOMAIN_RK3328(-1, 0, 0, false), + [RK3328_PD_GPU] = DOMAIN_RK3328(-1, 1, 1, false), + [RK3328_PD_BUS] = DOMAIN_RK3328(-1, 2, 2, true), + [RK3328_PD_MSCH] = DOMAIN_RK3328(-1, 3, 3, true), + [RK3328_PD_PERI] = DOMAIN_RK3328(-1, 4, 4, true), + [RK3328_PD_VIDEO] = DOMAIN_RK3328(-1, 5, 5, false), + [RK3328_PD_HEVC] = DOMAIN_RK3328(-1, 6, 6, false), + [RK3328_PD_VIO] = DOMAIN_RK3328(-1, 8, 8, false), + [RK3328_PD_VPU] = DOMAIN_RK3328(-1, 9, 9, false), +}; + static const struct rockchip_domain_info rk3368_pm_domains[] = { [RK3368_PD_PERI] = DOMAIN_RK3368(13, 12, 6, true), [RK3368_PD_VIO] = DOMAIN_RK3368(15, 14, 8, false), @@ -769,6 +785,15 @@ static const struct rockchip_pmu_info rk3288_pmu = { .domain_info = rk3288_pm_domains, }; +static const struct rockchip_pmu_info rk3328_pmu = { + .req_offset = 0x414, + .idle_offset = 0x484, + .ack_offset = 0x484, + + .num_domains = ARRAY_SIZE(rk3328_pm_domains), + .domain_info = rk3328_pm_domains, +}; + static const struct rockchip_pmu_info rk3368_pmu = { .pwr_offset = 0x0c, .status_offset = 0x10, @@ -804,6 +829,10 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = { .compatible = "rockchip,rk3288-power-controller", .data = (void *)&rk3288_pmu, }, + { + .compatible = "rockchip,rk3328-power-controller", + .data = (void *)&rk3328_pmu, + }, { .compatible = "rockchip,rk3368-power-controller", .data = (void *)&rk3368_pmu, -- cgit v1.2.3 From 4c58063d4258f6beb4fd5647db6b58f49e337c8f Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 17 Nov 2016 00:03:03 +0100 Subject: soc: rockchip: add driver handling grf setup The General Register Files are an area of registers containing a lot of single-bit settings for numerous components as well full components like usbphy control. Therefore all used components are accessed via the syscon provided by the grf nodes or from the sub-devices created through the simple-mfd created from the grf node. Some settings are not used by anything but will need to be set up according to expectations on the kernel side. Best example is the force_jtag setting, which defaults to on and results in the soc switching the pin-outputs between jtag and sdmmc automatically depending on the card-detect status. This conflicts heavily with how the dw_mmc driver expects to do its work and also with the clock-controller, which has most likely deactivated the jtag clock due to it being unused. So far the handling of this setting was living in the mach-rockchip code for the arm32-based rk3288 but that of course doesn't work for arm64 socs and would also look ugly for further arm32 socs. Also always disabling this setting is quite specific to linux and its subsystems, other operating systems might prefer other settings, so that the bootloader cannot really set a sane default for all. So introduce a top-level driver for the grf that handles these settings that need to be a certain way but nobody cares about. Other needed settings might surface in the future and can then be added here, but only as a last option. Ideally general GRF settings should be handled in the driver needing them. Signed-off-by: Heiko Stuebner Reviewed-by: Douglas Anderson --- drivers/soc/rockchip/Kconfig | 10 ++++ drivers/soc/rockchip/Makefile | 1 + drivers/soc/rockchip/grf.c | 134 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 drivers/soc/rockchip/grf.c (limited to 'drivers/soc') diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig index 7140ff8255987..20da55d9cbb1e 100644 --- a/drivers/soc/rockchip/Kconfig +++ b/drivers/soc/rockchip/Kconfig @@ -3,6 +3,16 @@ if ARCH_ROCKCHIP || COMPILE_TEST # # Rockchip Soc drivers # + +config ROCKCHIP_GRF + bool + default y + help + The General Register Files are a central component providing + special additional settings registers for a lot of soc-components. + In a lot of cases there also need to be default settings initialized + to make some of them conform to expectations of the kernel. + config ROCKCHIP_PM_DOMAINS bool "Rockchip generic power domain" depends on PM diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile index 3d73d0672d22d..c851fa0056d06 100644 --- a/drivers/soc/rockchip/Makefile +++ b/drivers/soc/rockchip/Makefile @@ -1,4 +1,5 @@ # # Rockchip Soc drivers # +obj-$(CONFIG_ROCKCHIP_GRF) += grf.o obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c new file mode 100644 index 0000000000000..d61db34ad6ddf --- /dev/null +++ b/drivers/soc/rockchip/grf.c @@ -0,0 +1,134 @@ +/* + * Rockchip Generic Register Files setup + * + * Copyright (c) 2016 Heiko Stuebner + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define HIWORD_UPDATE(val, mask, shift) \ + ((val) << (shift) | (mask) << ((shift) + 16)) + +struct rockchip_grf_value { + const char *desc; + u32 reg; + u32 val; +}; + +struct rockchip_grf_info { + const struct rockchip_grf_value *values; + int num_values; +}; + +#define RK3036_GRF_SOC_CON0 0x140 + +static const struct rockchip_grf_value rk3036_defaults[] __initconst = { + /* + * Disable auto jtag/sdmmc switching that causes issues with the + * clock-framework and the mmc controllers making them unreliable. + */ + { "jtag switching", RK3036_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 11) }, +}; + +static const struct rockchip_grf_info rk3036_grf __initconst = { + .values = rk3036_defaults, + .num_values = ARRAY_SIZE(rk3036_defaults), +}; + +#define RK3288_GRF_SOC_CON0 0x244 + +static const struct rockchip_grf_value rk3288_defaults[] __initconst = { + { "jtag switching", RK3288_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 12) }, +}; + +static const struct rockchip_grf_info rk3288_grf __initconst = { + .values = rk3288_defaults, + .num_values = ARRAY_SIZE(rk3288_defaults), +}; + +#define RK3368_GRF_SOC_CON15 0x43c + +static const struct rockchip_grf_value rk3368_defaults[] __initconst = { + { "jtag switching", RK3368_GRF_SOC_CON15, HIWORD_UPDATE(0, 1, 13) }, +}; + +static const struct rockchip_grf_info rk3368_grf __initconst = { + .values = rk3368_defaults, + .num_values = ARRAY_SIZE(rk3368_defaults), +}; + +#define RK3399_GRF_SOC_CON7 0xe21c + +static const struct rockchip_grf_value rk3399_defaults[] __initconst = { + { "jtag switching", RK3399_GRF_SOC_CON7, HIWORD_UPDATE(0, 1, 12) }, +}; + +static const struct rockchip_grf_info rk3399_grf __initconst = { + .values = rk3399_defaults, + .num_values = ARRAY_SIZE(rk3399_defaults), +}; + +static const struct of_device_id rockchip_grf_dt_match[] __initconst = { + { + .compatible = "rockchip,rk3036-grf", + .data = (void *)&rk3036_grf, + }, { + .compatible = "rockchip,rk3288-grf", + .data = (void *)&rk3288_grf, + }, { + .compatible = "rockchip,rk3368-grf", + .data = (void *)&rk3368_grf, + }, { + .compatible = "rockchip,rk3399-grf", + .data = (void *)&rk3399_grf, + }, + { /* sentinel */ }, +}; + +static int __init rockchip_grf_init(void) +{ + const struct rockchip_grf_info *grf_info; + const struct of_device_id *match; + struct device_node *np; + struct regmap *grf; + int ret, i; + + np = of_find_matching_node_and_match(NULL, rockchip_grf_dt_match, + &match); + if (!np) + return -ENODEV; + if (!match || !match->data) { + pr_err("%s: missing grf data\n", __func__); + return -EINVAL; + } + + grf_info = match->data; + + grf = syscon_node_to_regmap(np); + if (IS_ERR(grf)) { + pr_err("%s: could not get grf syscon\n", __func__); + return PTR_ERR(grf); + } + + for (i = 0; i < grf_info->num_values; i++) { + const struct rockchip_grf_value *val = &grf_info->values[i]; + + pr_debug("%s: adjusting %s in %#6x to %#10x\n", __func__, + val->desc, val->reg, val->val); + ret = regmap_write(grf, val->reg, val->val); + if (ret < 0) + pr_err("%s: write to %#6x failed with %d\n", + __func__, val->reg, ret); + } + + return 0; +} +postcore_initcall(rockchip_grf_init); -- cgit v1.2.3 From 36cc9fd9ce0fd0e4654890aa347d258616aef5fa Mon Sep 17 00:00:00 2001 From: Sarangdhar Joshi Date: Thu, 5 Jan 2017 14:00:15 -0800 Subject: soc: ti: wkup_m3_ipc: Drop wait from wkup_m3_rproc_boot_thread The function wkup_m3_rproc_boot_thread waits for asynchronous firmware loading to parse the resource table before calling rproc_boot(). However, as the resource table parsing has been moved to rproc_boot(), there's no need to wait for the asynchronous firmware loading completion. So, drop this. CC: Dave Gerlach CC: Bjorn Andersson Tested-by: Suman Anna Signed-off-by: Sarangdhar Joshi Signed-off-by: Tony Lindgren --- drivers/soc/ti/wkup_m3_ipc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c index 8823cc81ae453..8bfa44b08e03a 100644 --- a/drivers/soc/ti/wkup_m3_ipc.c +++ b/drivers/soc/ti/wkup_m3_ipc.c @@ -370,8 +370,6 @@ static void wkup_m3_rproc_boot_thread(struct wkup_m3_ipc *m3_ipc) struct device *dev = m3_ipc->dev; int ret; - wait_for_completion(&m3_ipc->rproc->firmware_loading_complete); - init_completion(&m3_ipc->sync_complete); ret = rproc_boot(m3_ipc->rproc); -- cgit v1.2.3 From 4ee34aae41082491aeb014d28abd6b19ac1c92c0 Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Fri, 6 Jan 2017 11:05:45 -0800 Subject: soc: ti: knav_dma: fix typos in trace message This patch fixes some typos in the trace message Signed-off-by: Murali Karicheri Signed-off-by: Sekhar Nori Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/knav_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index 1a7b5caa127b5..ecebe2eecc3aa 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -395,7 +395,7 @@ static int of_channel_match_helper(struct device_node *np, const char *name, if (of_parse_phandle_with_fixed_args(np, "ti,navigator-dmas", 1, index, &args)) { - dev_err(kdev->dev, "Missing the pahndle args name %s\n", name); + dev_err(kdev->dev, "Missing the phandle args name %s\n", name); return -ENODEV; } @@ -436,7 +436,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name, } dev_dbg(kdev->dev, "initializing %s channel %d from DMA %s\n", - config->direction == DMA_MEM_TO_DEV ? "transmit" : + config->direction == DMA_MEM_TO_DEV ? "transmit" : config->direction == DMA_DEV_TO_MEM ? "receive" : "unknown", chan_num, instance); -- cgit v1.2.3 From 6e03f653e318ac8d248a945082174b39733489f5 Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Fri, 6 Jan 2017 11:05:45 -0800 Subject: soc: ti: knav: cleanup includes and sort header files This patch cleanup the code to remove unnecessary header files and also sort the header files. Signed-off-by: Murali Karicheri Signed-off-by: WingMan Kwok Signed-off-by: Sekhar Nori Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/knav_qmss_acc.c | 15 +++------------ drivers/soc/ti/knav_qmss_queue.c | 25 ++++++++----------------- 2 files changed, 11 insertions(+), 29 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c index 0612ebae0a093..3d7225f4e77fe 100644 --- a/drivers/soc/ti/knav_qmss_acc.c +++ b/drivers/soc/ti/knav_qmss_acc.c @@ -16,21 +16,12 @@ * General Public License for more details. */ -#include -#include -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include +#include #include "knav_qmss.h" diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index eacad57f29776..279e7c5551dd5 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -16,26 +16,17 @@ * General Public License for more details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include +#include +#include +#include +#include #include +#include +#include #include -#include -#include -#include -#include +#include #include #include "knav_qmss.h" -- cgit v1.2.3 From 4c2c2e39713b8cfbb73d304c830e883f5b2ad9ec Mon Sep 17 00:00:00 2001 From: Baoyou Xie Date: Fri, 6 Jan 2017 17:16:03 +0800 Subject: soc: zte: pm_domains: Prepare for supporting ARMv8 zx2967 family The ARMv8 zx2967 family (296718, 296716 etc) uses different value for controlling the power domain on/off registers, Choose the value depending on the compatible. Multiple domains are prepared for the family, this patch prepares the common functions. Signed-off-by: Baoyou Xie Signed-off-by: Shawn Guo --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/zte/Kconfig | 13 ++++ drivers/soc/zte/Makefile | 4 + drivers/soc/zte/zx2967_pm_domains.c | 143 ++++++++++++++++++++++++++++++++++++ drivers/soc/zte/zx2967_pm_domains.h | 44 +++++++++++ 6 files changed, 206 insertions(+) create mode 100644 drivers/soc/zte/Kconfig create mode 100644 drivers/soc/zte/Makefile create mode 100644 drivers/soc/zte/zx2967_pm_domains.c create mode 100644 drivers/soc/zte/zx2967_pm_domains.h (limited to 'drivers/soc') diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index f31bceb69c0d0..f09023f7ab119 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -11,5 +11,6 @@ source "drivers/soc/tegra/Kconfig" source "drivers/soc/ti/Kconfig" source "drivers/soc/ux500/Kconfig" source "drivers/soc/versatile/Kconfig" +source "drivers/soc/zte/Kconfig" endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 50c23d0bd4570..05eae52a30b45 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-$(CONFIG_SOC_TI) += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_PLAT_VERSATILE) += versatile/ +obj-$(CONFIG_ARCH_ZX) += zte/ diff --git a/drivers/soc/zte/Kconfig b/drivers/soc/zte/Kconfig new file mode 100644 index 0000000000000..20bde38ce2f91 --- /dev/null +++ b/drivers/soc/zte/Kconfig @@ -0,0 +1,13 @@ +# +# ZTE SoC drivers +# +menuconfig SOC_ZTE + bool "ZTE SoC driver support" + +if SOC_ZTE + +config ZX2967_PM_DOMAINS + bool "ZX2967 PM domains" + depends on PM_GENERIC_DOMAINS + +endif diff --git a/drivers/soc/zte/Makefile b/drivers/soc/zte/Makefile new file mode 100644 index 0000000000000..8a37f2f7ed27e --- /dev/null +++ b/drivers/soc/zte/Makefile @@ -0,0 +1,4 @@ +# +# ZTE SOC drivers +# +obj-$(CONFIG_ZX2967_PM_DOMAINS) += zx2967_pm_domains.o diff --git a/drivers/soc/zte/zx2967_pm_domains.c b/drivers/soc/zte/zx2967_pm_domains.c new file mode 100644 index 0000000000000..61c8d84bf3156 --- /dev/null +++ b/drivers/soc/zte/zx2967_pm_domains.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2017 ZTE Ltd. + * + * Author: Baoyou Xie + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include + +#include "zx2967_pm_domains.h" + +#define PCU_DM_CLKEN(zpd) ((zpd)->reg_offset[REG_CLKEN]) +#define PCU_DM_ISOEN(zpd) ((zpd)->reg_offset[REG_ISOEN]) +#define PCU_DM_RSTEN(zpd) ((zpd)->reg_offset[REG_RSTEN]) +#define PCU_DM_PWREN(zpd) ((zpd)->reg_offset[REG_PWREN]) +#define PCU_DM_ACK_SYNC(zpd) ((zpd)->reg_offset[REG_ACK_SYNC]) + +static void __iomem *pcubase; + +static int zx2967_power_on(struct generic_pm_domain *domain) +{ + struct zx2967_pm_domain *zpd = (struct zx2967_pm_domain *)domain; + unsigned long loop = 1000; + u32 val; + + val = readl_relaxed(pcubase + PCU_DM_PWREN(zpd)); + if (zpd->polarity == PWREN) + val |= BIT(zpd->bit); + else + val &= ~BIT(zpd->bit); + writel_relaxed(val, pcubase + PCU_DM_PWREN(zpd)); + + do { + udelay(1); + val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC(zpd)) + & BIT(zpd->bit); + } while (--loop && !val); + + if (!loop) { + pr_err("Error: %s %s fail\n", __func__, domain->name); + return -EIO; + } + + val = readl_relaxed(pcubase + PCU_DM_RSTEN(zpd)); + val |= BIT(zpd->bit); + writel_relaxed(val, pcubase + PCU_DM_RSTEN(zpd)); + udelay(5); + + val = readl_relaxed(pcubase + PCU_DM_ISOEN(zpd)); + val &= ~BIT(zpd->bit); + writel_relaxed(val, pcubase + PCU_DM_ISOEN(zpd)); + udelay(5); + + val = readl_relaxed(pcubase + PCU_DM_CLKEN(zpd)); + val |= BIT(zpd->bit); + writel_relaxed(val, pcubase + PCU_DM_CLKEN(zpd)); + udelay(5); + + pr_debug("poweron %s\n", domain->name); + + return 0; +} + +static int zx2967_power_off(struct generic_pm_domain *domain) +{ + struct zx2967_pm_domain *zpd = (struct zx2967_pm_domain *)domain; + unsigned long loop = 1000; + u32 val; + + val = readl_relaxed(pcubase + PCU_DM_CLKEN(zpd)); + val &= ~BIT(zpd->bit); + writel_relaxed(val, pcubase + PCU_DM_CLKEN(zpd)); + udelay(5); + + val = readl_relaxed(pcubase + PCU_DM_ISOEN(zpd)); + val |= BIT(zpd->bit); + writel_relaxed(val, pcubase + PCU_DM_ISOEN(zpd)); + udelay(5); + + val = readl_relaxed(pcubase + PCU_DM_RSTEN(zpd)); + val &= ~BIT(zpd->bit); + writel_relaxed(val, pcubase + PCU_DM_RSTEN(zpd)); + udelay(5); + + val = readl_relaxed(pcubase + PCU_DM_PWREN(zpd)); + if (zpd->polarity == PWREN) + val &= ~BIT(zpd->bit); + else + val |= BIT(zpd->bit); + writel_relaxed(val, pcubase + PCU_DM_PWREN(zpd)); + + do { + udelay(1); + val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC(zpd)) + & BIT(zpd->bit); + } while (--loop && val); + + if (!loop) { + pr_err("Error: %s %s fail\n", __func__, domain->name); + return -EIO; + } + + pr_debug("poweroff %s\n", domain->name); + + return 0; +} + +int zx2967_pd_probe(struct platform_device *pdev, + struct generic_pm_domain **zx_pm_domains, + int domain_num) +{ + struct genpd_onecell_data *genpd_data; + struct resource *res; + int i; + + genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL); + if (!genpd_data) + return -ENOMEM; + + genpd_data->domains = zx_pm_domains; + genpd_data->num_domains = domain_num; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pcubase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pcubase)) { + dev_err(&pdev->dev, "ioremap fail.\n"); + return PTR_ERR(pcubase); + } + + for (i = 0; i < domain_num; ++i) { + zx_pm_domains[i]->power_on = zx2967_power_on; + zx_pm_domains[i]->power_off = zx2967_power_off; + + pm_genpd_init(zx_pm_domains[i], NULL, false); + } + + of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data); + dev_info(&pdev->dev, "powerdomain init ok\n"); + return 0; +} diff --git a/drivers/soc/zte/zx2967_pm_domains.h b/drivers/soc/zte/zx2967_pm_domains.h new file mode 100644 index 0000000000000..cb46595a7ff3b --- /dev/null +++ b/drivers/soc/zte/zx2967_pm_domains.h @@ -0,0 +1,44 @@ +/* + * Header for ZTE's Power Domain Driver support + * + * Copyright (C) 2017 ZTE Ltd. + * + * Author: Baoyou Xie + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __ZTE_ZX2967_PM_DOMAIN_H +#define __ZTE_ZX2967_PM_DOMAIN_H + +#include +#include + +enum { + REG_CLKEN, + REG_ISOEN, + REG_RSTEN, + REG_PWREN, + REG_PWRDN, + REG_ACK_SYNC, + + /* The size of the array - must be last */ + REG_ARRAY_SIZE, +}; + +enum zx2967_power_polarity { + PWREN, + PWRDN, +}; + +struct zx2967_pm_domain { + struct generic_pm_domain dm; + const u16 bit; + const enum zx2967_power_polarity polarity; + const u16 *reg_offset; +}; + +int zx2967_pd_probe(struct platform_device *pdev, + struct generic_pm_domain **zx_pm_domains, + int domain_num); + +#endif /* __ZTE_ZX2967_PM_DOMAIN_H */ -- cgit v1.2.3 From 3755584a91c1cb1e50dd24a456e2953fbd276adf Mon Sep 17 00:00:00 2001 From: Baoyou Xie Date: Fri, 6 Jan 2017 17:16:04 +0800 Subject: soc: zte: pm_domains: Add support for zx296718 This patch introduces the power domain driver of zx296718 which belongs to zte's zx2967 family. Signed-off-by: Baoyou Xie Reviewed-by: Jun Nie Signed-off-by: Shawn Guo --- drivers/soc/zte/Makefile | 1 + drivers/soc/zte/zx296718_pm_domains.c | 182 ++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 drivers/soc/zte/zx296718_pm_domains.c (limited to 'drivers/soc') diff --git a/drivers/soc/zte/Makefile b/drivers/soc/zte/Makefile index 8a37f2f7ed27e..96b7cd4c9629f 100644 --- a/drivers/soc/zte/Makefile +++ b/drivers/soc/zte/Makefile @@ -2,3 +2,4 @@ # ZTE SOC drivers # obj-$(CONFIG_ZX2967_PM_DOMAINS) += zx2967_pm_domains.o +obj-$(CONFIG_ZX2967_PM_DOMAINS) += zx296718_pm_domains.o diff --git a/drivers/soc/zte/zx296718_pm_domains.c b/drivers/soc/zte/zx296718_pm_domains.c new file mode 100644 index 0000000000000..5ed924fee855c --- /dev/null +++ b/drivers/soc/zte/zx296718_pm_domains.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2017 ZTE Ltd. + * + * Author: Baoyou Xie + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include "zx2967_pm_domains.h" + +static u16 zx296718_offsets[REG_ARRAY_SIZE] = { + [REG_CLKEN] = 0x18, + [REG_ISOEN] = 0x1c, + [REG_RSTEN] = 0x20, + [REG_PWREN] = 0x24, + [REG_ACK_SYNC] = 0x28, +}; + +enum { + PCU_DM_VOU = 0, + PCU_DM_SAPPU, + PCU_DM_VDE, + PCU_DM_VCE, + PCU_DM_HDE, + PCU_DM_VIU, + PCU_DM_USB20, + PCU_DM_USB21, + PCU_DM_USB30, + PCU_DM_HSIC, + PCU_DM_GMAC, + PCU_DM_TS, +}; + +static struct zx2967_pm_domain vou_domain = { + .dm = { + .name = "vou_domain", + }, + .bit = PCU_DM_VOU, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain sappu_domain = { + .dm = { + .name = "sappu_domain", + }, + .bit = PCU_DM_SAPPU, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain vde_domain = { + .dm = { + .name = "vde_domain", + }, + .bit = PCU_DM_VDE, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain vce_domain = { + .dm = { + .name = "vce_domain", + }, + .bit = PCU_DM_VCE, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain hde_domain = { + .dm = { + .name = "hde_domain", + }, + .bit = PCU_DM_HDE, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain viu_domain = { + .dm = { + .name = "viu_domain", + }, + .bit = PCU_DM_VIU, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain usb20_domain = { + .dm = { + .name = "usb20_domain", + }, + .bit = PCU_DM_USB20, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain usb21_domain = { + .dm = { + .name = "usb21_domain", + }, + .bit = PCU_DM_USB21, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain usb30_domain = { + .dm = { + .name = "usb30_domain", + }, + .bit = PCU_DM_USB30, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain hsic_domain = { + .dm = { + .name = "hsic_domain", + }, + .bit = PCU_DM_HSIC, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain gmac_domain = { + .dm = { + .name = "gmac_domain", + }, + .bit = PCU_DM_GMAC, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct zx2967_pm_domain ts_domain = { + .dm = { + .name = "ts_domain", + }, + .bit = PCU_DM_TS, + .polarity = PWREN, + .reg_offset = zx296718_offsets, +}; + +static struct generic_pm_domain *zx296718_pm_domains[] = { + [DM_ZX296718_VOU] = &vou_domain.dm, + [DM_ZX296718_SAPPU] = &sappu_domain.dm, + [DM_ZX296718_VDE] = &vde_domain.dm, + [DM_ZX296718_VCE] = &vce_domain.dm, + [DM_ZX296718_HDE] = &hde_domain.dm, + [DM_ZX296718_VIU] = &viu_domain.dm, + [DM_ZX296718_USB20] = &usb20_domain.dm, + [DM_ZX296718_USB21] = &usb21_domain.dm, + [DM_ZX296718_USB30] = &usb30_domain.dm, + [DM_ZX296718_HSIC] = &hsic_domain.dm, + [DM_ZX296718_GMAC] = &gmac_domain.dm, + [DM_ZX296718_TS] = &ts_domain.dm, +}; + +static int zx296718_pd_probe(struct platform_device *pdev) +{ + return zx2967_pd_probe(pdev, + zx296718_pm_domains, + ARRAY_SIZE(zx296718_pm_domains)); +} + +static const struct of_device_id zx296718_pm_domain_matches[] = { + { .compatible = "zte,zx296718-pcu", }, + { }, +}; + +static struct platform_driver zx296718_pd_driver = { + .driver = { + .name = "zx296718-powerdomain", + .owner = THIS_MODULE, + .of_match_table = zx296718_pm_domain_matches, + }, + .probe = zx296718_pd_probe, +}; + +static int __init zx296718_pd_init(void) +{ + return platform_driver_register(&zx296718_pd_driver); +} +subsys_initcall(zx296718_pd_init); -- cgit v1.2.3 From fa59aa70907b2e5c08f58d63ed7c1e5017e39301 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 26 Jan 2017 09:33:47 +0100 Subject: soc: samsung: pmu: Add dummy support for Exynos5433 SoC Add compatible for Exynos5433 SoC, so the driver will bind and let other drivers to use PMU regmap. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/exynos-pmu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index 813df6e7292d7..56d9244ff9814 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -44,7 +44,7 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode) unsigned int i; const struct exynos_pmu_data *pmu_data; - if (!pmu_context) + if (!pmu_context || !pmu_context->pmu_data) return; pmu_data = pmu_context->pmu_data; @@ -90,6 +90,8 @@ static const struct of_device_id exynos_pmu_of_device_ids[] = { }, { .compatible = "samsung,exynos5420-pmu", .data = &exynos5420_pmu_data, + }, { + .compatible = "samsung,exynos5433-pmu", }, { /*sentinel*/ }, }; @@ -122,7 +124,7 @@ static int exynos_pmu_probe(struct platform_device *pdev) pmu_context->dev = dev; pmu_context->pmu_data = of_device_get_match_data(dev); - if (pmu_context->pmu_data->pmu_init) + if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init) pmu_context->pmu_data->pmu_init(); platform_set_drvdata(pdev, pmu_context); -- cgit v1.2.3 From 6bce1974f64aba108ad344cb2ef0110d9c09ebd2 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 25 Jan 2017 12:55:35 +0100 Subject: soc: samsung: pm_domains: Add new Exynos5433 compatible Add a new compatible string for Exynos5433 because it uses the 0xf value instead of 0x7 for domain on/off registers. Signed-off-by: Jonghwa Lee Signed-off-by: Chanwoo Choi Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/power/pd-samsung.txt | 1 + drivers/soc/samsung/pm_domains.c | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'drivers/soc') diff --git a/Documentation/devicetree/bindings/power/pd-samsung.txt b/Documentation/devicetree/bindings/power/pd-samsung.txt index 4e947372a6932..f5d4b68d2760d 100644 --- a/Documentation/devicetree/bindings/power/pd-samsung.txt +++ b/Documentation/devicetree/bindings/power/pd-samsung.txt @@ -6,6 +6,7 @@ to gate power to one or more peripherals on the processor. Required Properties: - compatible: should be one of the following. * samsung,exynos4210-pd - for exynos4210 type power domain. + * samsung,exynos5433-pd - for exynos5433 type power domain. - reg: physical base address of the controller and length of memory mapped region. - #power-domain-cells: number of cells in power domain specifier; diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index 7112004b80326..15bad1543409b 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -128,10 +128,17 @@ static const struct exynos_pm_domain_config exynos4210_cfg __initconst = { .local_pwr_cfg = 0x7, }; +static const struct exynos_pm_domain_config exynos5433_cfg __initconst = { + .local_pwr_cfg = 0xf, +}; + static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { { .compatible = "samsung,exynos4210-pd", .data = &exynos4210_cfg, + }, { + .compatible = "samsung,exynos5433-pd", + .data = &exynos5433_cfg, }, { }, }; -- cgit v1.2.3 From ee55ae6194a5439bde3a3b8ee0abda63c610e740 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 25 Jan 2017 21:09:44 +0200 Subject: soc: samsung: pmu: Remove duplicated define for ARM_L2_OPTION register The register ARM_L2_OPTION (0x2608 in Exynos4 and Exynos5 PMU) was defined twice. Both names were used in the Exynos542x code. Simplify this. Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/suspend.c | 6 +++--- drivers/soc/samsung/exynos5250-pmu.c | 2 +- drivers/soc/samsung/exynos5420-pmu.c | 4 ++-- include/linux/soc/samsung/exynos-regs-pmu.h | 3 +-- 4 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/soc') diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 06332f6265652..bf97de884eeae 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -388,9 +388,9 @@ static void exynos5420_pm_prepare(void) if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0); - tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION); - tmp &= ~EXYNOS5_USE_RETENTION; - pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); + tmp = pmu_raw_readl(EXYNOS_L2_OPTION(0)); + tmp &= ~EXYNOS_L2_USE_RETENTION; + pmu_raw_writel(tmp, EXYNOS_L2_OPTION(0)); tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); tmp |= EXYNOS5420_UFS; diff --git a/drivers/soc/samsung/exynos5250-pmu.c b/drivers/soc/samsung/exynos5250-pmu.c index 3fac42561964c..8d94f0819f320 100644 --- a/drivers/soc/samsung/exynos5250-pmu.c +++ b/drivers/soc/samsung/exynos5250-pmu.c @@ -29,7 +29,7 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = { { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, - { EXYNOS5_ARM_L2_OPTION, { 0x10, 0x10, 0x0 } }, + { EXYNOS_L2_OPTION(0), { 0x10, 0x10, 0x0 } }, { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, diff --git a/drivers/soc/samsung/exynos5420-pmu.c b/drivers/soc/samsung/exynos5420-pmu.c index 3f2c64180ef82..0a89fa79c678d 100644 --- a/drivers/soc/samsung/exynos5420-pmu.c +++ b/drivers/soc/samsung/exynos5420-pmu.c @@ -230,11 +230,11 @@ static void exynos5420_pmu_init(void) pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); value = pmu_raw_readl(EXYNOS_L2_OPTION(0)); - value &= ~EXYNOS5_USE_RETENTION; + value &= ~EXYNOS_L2_USE_RETENTION; pmu_raw_writel(value, EXYNOS_L2_OPTION(0)); value = pmu_raw_readl(EXYNOS_L2_OPTION(1)); - value &= ~EXYNOS5_USE_RETENTION; + value &= ~EXYNOS_L2_USE_RETENTION; pmu_raw_writel(value, EXYNOS_L2_OPTION(1)); /* diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h index 9793502a6a57f..9786c62d7159e 100644 --- a/include/linux/soc/samsung/exynos-regs-pmu.h +++ b/include/linux/soc/samsung/exynos-regs-pmu.h @@ -149,8 +149,7 @@ #define EXYNOS_L2_OPTION(_nr) \ (EXYNOS_L2_CONFIGURATION(_nr) + 0x8) -#define EXYNOS5_ARM_L2_OPTION 0x2608 -#define EXYNOS5_USE_RETENTION BIT(4) +#define EXYNOS_L2_USE_RETENTION BIT(4) #define S5P_PAD_RET_MAUDIO_OPTION 0x3028 #define S5P_PAD_RET_MMC2_OPTION 0x30c8 -- cgit v1.2.3 From 402e73c5192b78ea4734f1c76fb7e68d9a41e3e2 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 30 Jan 2017 13:18:56 +0100 Subject: soc: samsung: pm_domains: Use full names in subdomains registration log Device tree none name for each power domain should be "power-domain", so use a bit more descriptive full node name in messages about subdomain registration. This way the following meaningless message: power-domain has as child subdomain: power-domain. is changed to a bit more meaningful one: /soc/power-domain@105c40a0 has as child subdomain: /soc/power-domain@105c4020. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/pm_domains.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index 7112004b80326..f265d326e1321 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -227,10 +227,10 @@ no_clk: if (of_genpd_add_subdomain(&parent, &child)) pr_warn("%s failed to add subdomain: %s\n", - parent.np->name, child.np->name); + parent.np->full_name, child.np->full_name); else pr_info("%s has as child subdomain: %s.\n", - parent.np->name, child.np->name); + parent.np->full_name, child.np->full_name); } return 0; -- cgit v1.2.3 From 066502d483dead0417841c5fa7cddb0a50f828e1 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 30 Jan 2017 13:18:57 +0100 Subject: soc: samsung: pm_domains: Remove unused name field Name is now in generic pm domain structure, so there is no need to duplicate it in private data. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/pm_domains.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index f265d326e1321..05f63fe96920d 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -35,7 +35,6 @@ struct exynos_pm_domain_config { */ struct exynos_pm_domain { void __iomem *base; - char const *name; bool is_off; struct generic_pm_domain pd; struct clk *oscclk; @@ -70,7 +69,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) 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); + domain->name, i); } } @@ -101,7 +100,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) 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", - pd->name, i); + domain->name, i); } } @@ -163,7 +162,6 @@ static __init int exynos4_pm_init_power_domain(void) return -ENOMEM; } - pd->name = pd->pd.name; pd->base = of_iomap(np, 0); if (!pd->base) { pr_warn("%s: failed to map memory\n", __func__); -- cgit v1.2.3 From d1a09872fe2f28bf1a9e224abaf1688807adda91 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 30 Jan 2017 13:18:58 +0100 Subject: soc: samsung: pm_domains: Remove message about failed memory allocation Memory subsystem already prints message about failed memory allocation, there is no need to do it in the drivers. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/pm_domains.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index 05f63fe96920d..0649024fce092 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -149,8 +149,6 @@ static __init int exynos4_pm_init_power_domain(void) pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) { - pr_err("%s: failed to allocate memory for domain\n", - __func__); of_node_put(np); return -ENOMEM; } -- cgit v1.2.3 From b13b2330aab53af4ebaa2859f72f2c802d01abad Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 30 Jan 2017 13:18:59 +0100 Subject: soc: samsung: pm_domains: Read domain name from the new label property Device tree nodes for each power domain should use generic "power-domain" name, so using it as a domain name doesn't give much benefits. This patch adds support for human readable names defined in 'label' property. Such names are visible to userspace and makes debugging much easier. When no 'label' property is found, driver keeps using the name constructed from full node name. Suggested-by: Krzysztof Kozlowski Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/power/pd-samsung.txt | 4 ++++ drivers/soc/samsung/pm_domains.c | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/Documentation/devicetree/bindings/power/pd-samsung.txt b/Documentation/devicetree/bindings/power/pd-samsung.txt index 4e947372a6932..c461b1090cb64 100644 --- a/Documentation/devicetree/bindings/power/pd-samsung.txt +++ b/Documentation/devicetree/bindings/power/pd-samsung.txt @@ -12,6 +12,8 @@ Required Properties: must be 0. Optional Properties: +- label: Human readable string with domain name. Will be visible in userspace + 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 @@ -38,6 +40,7 @@ Example: compatible = "samsung,exynos4210-pd"; reg = <0x10023C00 0x10>; #power-domain-cells = <0>; + label = "LCD0"; }; mfc_pd: power-domain@10044060 { @@ -46,6 +49,7 @@ Example: clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_USER_ACLK333>; clock-names = "oscclk", "clk0"; #power-domain-cells = <0>; + label = "MFC"; }; See Documentation/devicetree/bindings/power/power_domain.txt for description diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index 0649024fce092..31270171f23d3 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -135,6 +135,15 @@ static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { { }, }; +static __init const char *exynos_get_domain_name(struct device_node *node) +{ + const char *name; + + if (of_property_read_string(node, "label", &name) < 0) + name = strrchr(node->full_name, '/') + 1; + return kstrdup_const(name, GFP_KERNEL); +} + static __init int exynos4_pm_init_power_domain(void) { struct device_node *np; @@ -152,8 +161,7 @@ static __init int exynos4_pm_init_power_domain(void) of_node_put(np); return -ENOMEM; } - pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1, - GFP_KERNEL); + pd->pd.name = exynos_get_domain_name(np); if (!pd->pd.name) { kfree(pd); of_node_put(np); -- cgit v1.2.3