diff options
author | Andreas Färber <afaerber@suse.de> | 2017-06-05 21:04:21 +0200 |
---|---|---|
committer | Andreas Färber <afaerber@suse.de> | 2017-06-23 17:43:27 +0200 |
commit | 6932ec60cc0a71689150b16b71427cfdc6575602 (patch) | |
tree | 27942772c2ef4d35444d6c4ef7c48e36663d9855 | |
parent | aa9f800ded78d530bb07104a4745e95af723abf6 (diff) | |
download | lwn-6932ec60cc0a71689150b16b71427cfdc6575602.tar.gz lwn-6932ec60cc0a71689150b16b71427cfdc6575602.zip |
soc: actions: owl-sps: Factor out owl_sps_set_pg() for power-gating
Allow the SMP code to reuse PM domain code for CPU2/CPU3 wakeup.
Signed-off-by: Andreas Färber <afaerber@suse.de>
-rw-r--r-- | drivers/soc/actions/Kconfig | 4 | ||||
-rw-r--r-- | drivers/soc/actions/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/actions/owl-sps-helper.c | 51 | ||||
-rw-r--r-- | drivers/soc/actions/owl-sps.c | 34 | ||||
-rw-r--r-- | include/linux/soc/actions/owl-sps.h | 11 |
5 files changed, 70 insertions, 31 deletions
diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig index bdf827d5ce78..9d68b5a771c3 100644 --- a/drivers/soc/actions/Kconfig +++ b/drivers/soc/actions/Kconfig @@ -1,8 +1,12 @@ if ARCH_ACTIONS || COMPILE_TEST +config OWL_PM_DOMAINS_HELPER + bool + config OWL_PM_DOMAINS bool "Actions Semi SPS power domains" depends on PM + select OWL_PM_DOMAINS_HELPER select PM_GENERIC_DOMAINS help Say 'y' here to enable support for Smart Power System (SPS) diff --git a/drivers/soc/actions/Makefile b/drivers/soc/actions/Makefile index 720c34ed16e4..1e101b06bab1 100644 --- a/drivers/soc/actions/Makefile +++ b/drivers/soc/actions/Makefile @@ -1 +1,2 @@ +obj-$(CONFIG_OWL_PM_DOMAINS_HELPER) += owl-sps-helper.o obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o diff --git a/drivers/soc/actions/owl-sps-helper.c b/drivers/soc/actions/owl-sps-helper.c new file mode 100644 index 000000000000..9d7a2c2b44ec --- /dev/null +++ b/drivers/soc/actions/owl-sps-helper.c @@ -0,0 +1,51 @@ +/* + * Actions Semi Owl Smart Power System (SPS) shared helpers + * + * Copyright 2012 Actions Semi Inc. + * Author: Actions Semi, Inc. + * + * Copyright (c) 2017 Andreas Färber + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/delay.h> +#include <linux/io.h> + +#define OWL_SPS_PG_CTL 0x0 + +int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable) +{ + u32 val; + bool ack; + int timeout; + + val = readl(base + OWL_SPS_PG_CTL); + ack = val & ack_mask; + if (ack == enable) + return 0; + + if (enable) + val |= pwr_mask; + else + val &= ~pwr_mask; + + writel(val, base + OWL_SPS_PG_CTL); + + for (timeout = 5000; timeout > 0; timeout -= 50) { + val = readl(base + OWL_SPS_PG_CTL); + if ((val & ack_mask) == (enable ? ack_mask : 0)) + break; + udelay(50); + } + if (timeout <= 0) + return -ETIMEDOUT; + + udelay(10); + + return 0; +} +EXPORT_SYMBOL_GPL(owl_sps_set_pg); diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c index 8abb72f01929..875225bfa21c 100644 --- a/drivers/soc/actions/owl-sps.c +++ b/drivers/soc/actions/owl-sps.c @@ -12,15 +12,12 @@ * option) any later version. */ -#include <linux/delay.h> -#include <linux/io.h> #include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/pm_domain.h> +#include <linux/soc/actions/owl-sps.h> #include <dt-bindings/power/owl-s500-powergate.h> -#define OWL_SPS_PG_CTL 0x0 - struct owl_sps_domain_info { const char *name; int pwr_bit; @@ -51,37 +48,12 @@ struct owl_sps_domain { static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable) { - u32 val, pwr_mask, ack_mask; - int timeout; - bool ack; + u32 pwr_mask, ack_mask; ack_mask = BIT(pd->info->ack_bit); pwr_mask = BIT(pd->info->pwr_bit); - val = readl(pd->sps->base + OWL_SPS_PG_CTL); - ack = val & ack_mask; - - if (ack == enable) - return 0; - - if (enable) - val |= pwr_mask; - else - val &= ~pwr_mask; - - writel(val, pd->sps->base + OWL_SPS_PG_CTL); - for (timeout = 5000; timeout > 0; timeout -= 50) { - val = readl(pd->sps->base + OWL_SPS_PG_CTL); - if ((val & ack_mask) == (enable ? ack_mask : 0)) - break; - udelay(50); - } - if (timeout <= 0) - return -ETIMEDOUT; - - udelay(10); - - return 0; + return owl_sps_set_pg(pd->sps->base, pwr_mask, ack_mask, enable); } static int owl_sps_power_on(struct generic_pm_domain *domain) diff --git a/include/linux/soc/actions/owl-sps.h b/include/linux/soc/actions/owl-sps.h new file mode 100644 index 000000000000..33d0dbeceb55 --- /dev/null +++ b/include/linux/soc/actions/owl-sps.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef SOC_ACTIONS_OWL_SPS_H +#define SOC_ACTIONS_OWL_SPS_H + +int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable); + +#endif |