diff options
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/soc/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/fsl/qe/qe_common.c | 20 | ||||
-rw-r--r-- | drivers/soc/imx/Kconfig | 2 | ||||
-rw-r--r-- | drivers/soc/litex/Kconfig | 1 | ||||
-rw-r--r-- | drivers/soc/litex/litex_soc_ctrl.c | 3 | ||||
-rw-r--r-- | drivers/soc/renesas/rcar-sysc.c | 37 | ||||
-rw-r--r-- | drivers/soc/samsung/Kconfig | 12 | ||||
-rw-r--r-- | drivers/soc/samsung/Makefile | 3 | ||||
-rw-r--r-- | drivers/soc/samsung/exynos-asv.c | 57 | ||||
-rw-r--r-- | drivers/soc/samsung/exynos-asv.h | 2 | ||||
-rw-r--r-- | drivers/soc/samsung/exynos-chipid.c | 71 | ||||
-rw-r--r-- | drivers/soc/samsung/pm_domains.c | 97 | ||||
-rw-r--r-- | drivers/soc/sunxi/sunxi_mbus.c | 5 | ||||
-rw-r--r-- | drivers/soc/ti/omap_prm.c | 11 | ||||
-rw-r--r-- | drivers/soc/zte/Kconfig | 15 | ||||
-rw-r--r-- | drivers/soc/zte/Makefile | 6 | ||||
-rw-r--r-- | drivers/soc/zte/zx296718_pm_domains.c | 181 | ||||
-rw-r--r-- | drivers/soc/zte/zx2967_pm_domains.c | 141 | ||||
-rw-r--r-- | drivers/soc/zte/zx2967_pm_domains.h | 44 |
20 files changed, 173 insertions, 537 deletions
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index d097d070f579..f357c6c659d2 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -22,7 +22,6 @@ source "drivers/soc/ti/Kconfig" source "drivers/soc/ux500/Kconfig" source "drivers/soc/versatile/Kconfig" source "drivers/soc/xilinx/Kconfig" -source "drivers/soc/zte/Kconfig" source "drivers/soc/kendryte/Kconfig" endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 699b758d28e4..9bceb12b291d 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -28,5 +28,4 @@ obj-y += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_PLAT_VERSATILE) += versatile/ obj-y += xilinx/ -obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_SOC_KENDRYTE) += kendryte/ diff --git a/drivers/soc/fsl/qe/qe_common.c b/drivers/soc/fsl/qe/qe_common.c index 497a7e0fd027..654e9246ce6b 100644 --- a/drivers/soc/fsl/qe/qe_common.c +++ b/drivers/soc/fsl/qe/qe_common.c @@ -27,7 +27,7 @@ static struct gen_pool *muram_pool; static spinlock_t cpm_muram_lock; -static u8 __iomem *muram_vbase; +static void __iomem *muram_vbase; static phys_addr_t muram_pbase; struct muram_block { @@ -223,9 +223,9 @@ void __iomem *cpm_muram_addr(unsigned long offset) } EXPORT_SYMBOL(cpm_muram_addr); -unsigned long cpm_muram_offset(void __iomem *addr) +unsigned long cpm_muram_offset(const void __iomem *addr) { - return addr - (void __iomem *)muram_vbase; + return addr - muram_vbase; } EXPORT_SYMBOL(cpm_muram_offset); @@ -235,6 +235,18 @@ EXPORT_SYMBOL(cpm_muram_offset); */ dma_addr_t cpm_muram_dma(void __iomem *addr) { - return muram_pbase + ((u8 __iomem *)addr - muram_vbase); + return muram_pbase + (addr - muram_vbase); } EXPORT_SYMBOL(cpm_muram_dma); + +/* + * As cpm_muram_free, but takes the virtual address rather than the + * muram offset. + */ +void cpm_muram_free_addr(const void __iomem *addr) +{ + if (!addr) + return; + cpm_muram_free(cpm_muram_offset(addr)); +} +EXPORT_SYMBOL(cpm_muram_free_addr); diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig index a9370f4aacca..05812f8ae734 100644 --- a/drivers/soc/imx/Kconfig +++ b/drivers/soc/imx/Kconfig @@ -13,7 +13,7 @@ config SOC_IMX8M depends on ARCH_MXC || COMPILE_TEST default ARCH_MXC && ARM64 select SOC_BUS - select ARM_GIC_V3 if ARCH_MXC + select ARM_GIC_V3 if ARCH_MXC && ARCH_MULTI_V7 help If you say yes here you get support for the NXP i.MX8M family support, it will provide the SoC info like SoC family, diff --git a/drivers/soc/litex/Kconfig b/drivers/soc/litex/Kconfig index 7c6b009b6f6c..7a7c38282e11 100644 --- a/drivers/soc/litex/Kconfig +++ b/drivers/soc/litex/Kconfig @@ -8,6 +8,7 @@ config LITEX config LITEX_SOC_CONTROLLER tristate "Enable LiteX SoC Controller driver" depends on OF || COMPILE_TEST + depends on HAS_IOMEM select LITEX help This option enables the SoC Controller Driver which verifies diff --git a/drivers/soc/litex/litex_soc_ctrl.c b/drivers/soc/litex/litex_soc_ctrl.c index 1217cafdfd4d..9b0766384570 100644 --- a/drivers/soc/litex/litex_soc_ctrl.c +++ b/drivers/soc/litex/litex_soc_ctrl.c @@ -140,12 +140,13 @@ struct litex_soc_ctrl_device { void __iomem *base; }; +#ifdef CONFIG_OF static const struct of_device_id litex_soc_ctrl_of_match[] = { {.compatible = "litex,soc-controller"}, {}, }; - MODULE_DEVICE_TABLE(of, litex_soc_ctrl_of_match); +#endif /* CONFIG_OF */ static int litex_soc_ctrl_probe(struct platform_device *pdev) { diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 9b235fc90027..53387a72ca00 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/soc/renesas/rcar-sysc.h> #include "rcar-sysc.h" @@ -44,13 +45,13 @@ #define PWRER_OFFS 0x14 /* Power Shutoff/Resume Error */ -#define SYSCSR_RETRIES 100 +#define SYSCSR_TIMEOUT 100 #define SYSCSR_DELAY_US 1 #define PWRER_RETRIES 100 #define PWRER_DELAY_US 1 -#define SYSCISR_RETRIES 1000 +#define SYSCISR_TIMEOUT 1000 #define SYSCISR_DELAY_US 1 #define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */ @@ -68,7 +69,8 @@ static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val; static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on) { unsigned int sr_bit, reg_offs; - int k; + u32 val; + int ret; if (on) { sr_bit = SYSCSR_PONENB; @@ -79,13 +81,10 @@ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on) } /* Wait until SYSC is ready to accept a power request */ - for (k = 0; k < SYSCSR_RETRIES; k++) { - if (ioread32(rcar_sysc_base + SYSCSR) & BIT(sr_bit)) - break; - udelay(SYSCSR_DELAY_US); - } - - if (k == SYSCSR_RETRIES) + ret = readl_poll_timeout_atomic(rcar_sysc_base + SYSCSR, val, + val & BIT(sr_bit), SYSCSR_DELAY_US, + SYSCSR_TIMEOUT); + if (ret) return -EAGAIN; /* Submit power shutoff or power resume request */ @@ -99,10 +98,9 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) { unsigned int isr_mask = BIT(sysc_ch->isr_bit); unsigned int chan_mask = BIT(sysc_ch->chan_bit); - unsigned int status; + unsigned int status, k; unsigned long flags; - int ret = 0; - int k; + int ret; spin_lock_irqsave(&rcar_sysc_lock, flags); @@ -145,13 +143,10 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) } /* Wait until the power shutoff or resume request has completed * */ - for (k = 0; k < SYSCISR_RETRIES; k++) { - if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask) - break; - udelay(SYSCISR_DELAY_US); - } - - if (k == SYSCISR_RETRIES) + ret = readl_poll_timeout_atomic(rcar_sysc_base + SYSCISR, status, + status & isr_mask, SYSCISR_DELAY_US, + SYSCISR_TIMEOUT); + if (ret) ret = -EIO; iowrite32(isr_mask, rcar_sysc_base + SYSCISCR); @@ -439,6 +434,8 @@ static int __init rcar_sysc_pd_init(void) } error = of_genpd_add_provider_onecell(np, &domains->onecell_data); + if (!error) + of_node_set_flag(np, OF_POPULATED); out_put: of_node_put(np); diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig index fc7f48a92288..5745d7e5908e 100644 --- a/drivers/soc/samsung/Kconfig +++ b/drivers/soc/samsung/Kconfig @@ -7,21 +7,19 @@ menuconfig SOC_SAMSUNG if SOC_SAMSUNG -config EXYNOS_ASV - bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST - depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST - select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS - # There is no need to enable these drivers for ARMv8 config EXYNOS_ASV_ARM bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST - depends on EXYNOS_ASV + depends on EXYNOS_CHIPID config EXYNOS_CHIPID - bool "Exynos Chipid controller driver" if COMPILE_TEST + bool "Exynos ChipID controller and ASV driver" if COMPILE_TEST depends on ARCH_EXYNOS || COMPILE_TEST + select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS select MFD_SYSCON select SOC_BUS + help + Support for Samsung Exynos SoC ChipID and Adaptive Supply Voltage. config EXYNOS_PMU bool "Exynos PMU controller driver" if COMPILE_TEST diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile index 59e8e9453f27..0c523a8de4eb 100644 --- a/drivers/soc/samsung/Makefile +++ b/drivers/soc/samsung/Makefile @@ -1,9 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_EXYNOS_ASV) += exynos-asv.o obj-$(CONFIG_EXYNOS_ASV_ARM) += exynos5422-asv.o -obj-$(CONFIG_EXYNOS_CHIPID) += exynos-chipid.o +obj-$(CONFIG_EXYNOS_CHIPID) += exynos-chipid.o exynos-asv.o obj-$(CONFIG_EXYNOS_PMU) += exynos-pmu.o obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS) += exynos3250-pmu.o exynos4-pmu.o \ diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c index 8abf4dfaa5c5..d60af8acc391 100644 --- a/drivers/soc/samsung/exynos-asv.c +++ b/drivers/soc/samsung/exynos-asv.c @@ -2,7 +2,9 @@ /* * Copyright (c) 2019 Samsung Electronics Co., Ltd. * http://www.samsung.com/ + * Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org> * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> + * Author: Krzysztof Kozlowski <krzk@kernel.org> * * Samsung Exynos SoC Adaptive Supply Voltage support */ @@ -10,12 +12,7 @@ #include <linux/cpu.h> #include <linux/device.h> #include <linux/errno.h> -#include <linux/init.h> -#include <linux/mfd/syscon.h> -#include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> -#include <linux/platform_device.h> #include <linux/pm_opp.h> #include <linux/regmap.h> #include <linux/soc/samsung/exynos-chipid.h> @@ -111,7 +108,7 @@ static int exynos_asv_update_opps(struct exynos_asv *asv) return 0; } -static int exynos_asv_probe(struct platform_device *pdev) +int exynos_asv_init(struct device *dev, struct regmap *regmap) { int (*probe_func)(struct exynos_asv *asv); struct exynos_asv *asv; @@ -119,39 +116,39 @@ static int exynos_asv_probe(struct platform_device *pdev) u32 product_id = 0; int ret, i; - cpu_dev = get_cpu_device(0); - ret = dev_pm_opp_get_opp_count(cpu_dev); - if (ret < 0) - return -EPROBE_DEFER; - - asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL); + asv = devm_kzalloc(dev, sizeof(*asv), GFP_KERNEL); if (!asv) return -ENOMEM; - asv->chipid_regmap = device_node_to_regmap(pdev->dev.of_node); - if (IS_ERR(asv->chipid_regmap)) { - dev_err(&pdev->dev, "Could not find syscon regmap\n"); - return PTR_ERR(asv->chipid_regmap); + asv->chipid_regmap = regmap; + asv->dev = dev; + ret = regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, + &product_id); + if (ret < 0) { + dev_err(dev, "Cannot read revision from ChipID: %d\n", ret); + return -ENODEV; } - regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id); - switch (product_id & EXYNOS_MASK) { case 0xE5422000: probe_func = exynos5422_asv_init; break; default: - return -ENODEV; + dev_dbg(dev, "No ASV support for this SoC\n"); + devm_kfree(dev, asv); + return 0; } - ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin", + cpu_dev = get_cpu_device(0); + ret = dev_pm_opp_get_opp_count(cpu_dev); + if (ret < 0) + return -EPROBE_DEFER; + + ret = of_property_read_u32(dev->of_node, "samsung,asv-bin", &asv->of_bin); if (ret < 0) asv->of_bin = -EINVAL; - asv->dev = &pdev->dev; - dev_set_drvdata(&pdev->dev, asv); - for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) asv->subsys[i].asv = asv; @@ -161,17 +158,3 @@ static int exynos_asv_probe(struct platform_device *pdev) return exynos_asv_update_opps(asv); } - -static const struct of_device_id exynos_asv_of_device_ids[] = { - { .compatible = "samsung,exynos4210-chipid" }, - {} -}; - -static struct platform_driver exynos_asv_driver = { - .driver = { - .name = "exynos-asv", - .of_match_table = exynos_asv_of_device_ids, - }, - .probe = exynos_asv_probe, -}; -module_platform_driver(exynos_asv_driver); diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h index 3fd1f2acd999..dcbe154db31e 100644 --- a/drivers/soc/samsung/exynos-asv.h +++ b/drivers/soc/samsung/exynos-asv.h @@ -68,4 +68,6 @@ static inline u32 exynos_asv_opp_get_frequency(const struct exynos_asv_subsys *s return __asv_get_table_entry(&subsys->table, level, 0); } +int exynos_asv_init(struct device *dev, struct regmap *regmap); + #endif /* __LINUX_SOC_EXYNOS_ASV_H */ diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c index 1a76eade2ed6..5c1d0f97f766 100644 --- a/drivers/soc/samsung/exynos-chipid.c +++ b/drivers/soc/samsung/exynos-chipid.c @@ -2,20 +2,28 @@ /* * Copyright (c) 2019 Samsung Electronics Co., Ltd. * http://www.samsung.com/ + * Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org> * * Exynos - CHIP ID support * Author: Pankaj Dubey <pankaj.dubey@samsung.com> * Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> + * Author: Krzysztof Kozlowski <krzk@kernel.org> + * + * Samsung Exynos SoC Adaptive Supply Voltage and Chip ID support */ -#include <linux/io.h> +#include <linux/device.h> +#include <linux/errno.h> #include <linux/mfd/syscon.h> #include <linux/of.h> +#include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/slab.h> #include <linux/soc/samsung/exynos-chipid.h> #include <linux/sys_soc.h> +#include "exynos-asv.h" + static const struct exynos_soc_id { const char *name; unsigned int id; @@ -36,7 +44,7 @@ static const struct exynos_soc_id { { "EXYNOS7420", 0xE7420000 }, }; -static const char * __init product_id_to_soc_id(unsigned int product_id) +static const char *product_id_to_soc_id(unsigned int product_id) { int i; @@ -46,25 +54,17 @@ static const char * __init product_id_to_soc_id(unsigned int product_id) return NULL; } -static int __init exynos_chipid_early_init(void) +static int exynos_chipid_probe(struct platform_device *pdev) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; struct device_node *root; - struct device_node *syscon; struct regmap *regmap; u32 product_id; u32 revision; int ret; - syscon = of_find_compatible_node(NULL, NULL, - "samsung,exynos4210-chipid"); - if (!syscon) - return -ENODEV; - - regmap = device_node_to_regmap(syscon); - of_node_put(syscon); - + regmap = device_node_to_regmap(pdev->dev.of_node); if (IS_ERR(regmap)) return PTR_ERR(regmap); @@ -74,7 +74,8 @@ static int __init exynos_chipid_early_init(void) revision = product_id & EXYNOS_REV_MASK; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr), + GFP_KERNEL); if (!soc_dev_attr) return -ENOMEM; @@ -84,20 +85,24 @@ static int __init exynos_chipid_early_init(void) of_property_read_string(root, "model", &soc_dev_attr->machine); of_node_put(root); - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision); + soc_dev_attr->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "%x", revision); soc_dev_attr->soc_id = product_id_to_soc_id(product_id); if (!soc_dev_attr->soc_id) { pr_err("Unknown SoC\n"); - ret = -ENODEV; - goto err; + return -ENODEV; } /* please note that the actual registration will be deferred */ soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - ret = PTR_ERR(soc_dev); + if (IS_ERR(soc_dev)) + return PTR_ERR(soc_dev); + + ret = exynos_asv_init(&pdev->dev, regmap); + if (ret) goto err; - } + + platform_set_drvdata(pdev, soc_dev); dev_info(soc_device_to_device(soc_dev), "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n", @@ -106,9 +111,31 @@ static int __init exynos_chipid_early_init(void) return 0; err: - kfree(soc_dev_attr->revision); - kfree(soc_dev_attr); + soc_device_unregister(soc_dev); + return ret; } -arch_initcall(exynos_chipid_early_init); +static int exynos_chipid_remove(struct platform_device *pdev) +{ + struct soc_device *soc_dev = platform_get_drvdata(pdev); + + soc_device_unregister(soc_dev); + + return 0; +} + +static const struct of_device_id exynos_chipid_of_device_ids[] = { + { .compatible = "samsung,exynos4210-chipid" }, + {} +}; + +static struct platform_driver exynos_chipid_driver = { + .driver = { + .name = "exynos-chipid", + .of_match_table = exynos_chipid_of_device_ids, + }, + .probe = exynos_chipid_probe, + .remove = exynos_chipid_remove, +}; +builtin_platform_driver(exynos_chipid_driver); diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index ab8582971bfc..5ec0c13f0aaf 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -16,7 +16,7 @@ #include <linux/delay.h> #include <linux/of_address.h> #include <linux/of_platform.h> -#include <linux/sched.h> +#include <linux/pm_runtime.h> struct exynos_pm_domain_config { /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */ @@ -73,15 +73,15 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain) return exynos_pd_power(domain, false); } -static const struct exynos_pm_domain_config exynos4210_cfg __initconst = { +static const struct exynos_pm_domain_config exynos4210_cfg = { .local_pwr_cfg = 0x7, }; -static const struct exynos_pm_domain_config exynos5433_cfg __initconst = { +static const struct exynos_pm_domain_config exynos5433_cfg = { .local_pwr_cfg = 0xf, }; -static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { +static const struct of_device_id exynos_pm_domain_of_match[] = { { .compatible = "samsung,exynos4210-pd", .data = &exynos4210_cfg, @@ -92,7 +92,7 @@ static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { { }, }; -static __init const char *exynos_get_domain_name(struct device_node *node) +static const char *exynos_get_domain_name(struct device_node *node) { const char *name; @@ -101,60 +101,44 @@ static __init const char *exynos_get_domain_name(struct device_node *node) return kstrdup_const(name, GFP_KERNEL); } -static __init int exynos4_pm_init_power_domain(void) +static int exynos_pd_probe(struct platform_device *pdev) { - struct device_node *np; - const struct of_device_id *match; - - for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) { - const struct exynos_pm_domain_config *pm_domain_cfg; - struct exynos_pm_domain *pd; - int on; + const struct exynos_pm_domain_config *pm_domain_cfg; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct of_phandle_args child, parent; + struct exynos_pm_domain *pd; + int on, ret; - pm_domain_cfg = match->data; + pm_domain_cfg = of_device_get_match_data(dev); + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); - if (!pd) { - of_node_put(np); - return -ENOMEM; - } - pd->pd.name = exynos_get_domain_name(np); - if (!pd->pd.name) { - kfree(pd); - of_node_put(np); - return -ENOMEM; - } + pd->pd.name = exynos_get_domain_name(np); + if (!pd->pd.name) + return -ENOMEM; - pd->base = of_iomap(np, 0); - if (!pd->base) { - pr_warn("%s: failed to map memory\n", __func__); - kfree_const(pd->pd.name); - kfree(pd); - continue; - } - - pd->pd.power_off = exynos_pd_power_off; - pd->pd.power_on = exynos_pd_power_on; - pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; + pd->base = of_iomap(np, 0); + if (!pd->base) { + kfree_const(pd->pd.name); + return -ENODEV; + } - on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg; + pd->pd.power_off = exynos_pd_power_off; + pd->pd.power_on = exynos_pd_power_on; + pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; - pm_genpd_init(&pd->pd, NULL, !on); - of_genpd_add_provider_simple(np, &pd->pd); - } + on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg; - /* Assign the child power domains to their parents */ - for_each_matching_node(np, exynos_pm_domain_of_match) { - struct of_phandle_args child, parent; + pm_genpd_init(&pd->pd, NULL, !on); + ret = of_genpd_add_provider_simple(np, &pd->pd); + if (ret == 0 && of_parse_phandle_with_args(np, "power-domains", + "#power-domain-cells", 0, &parent) == 0) { child.np = np; child.args_count = 0; - if (of_parse_phandle_with_args(np, "power-domains", - "#power-domain-cells", 0, - &parent) != 0) - continue; - if (of_genpd_add_subdomain(&parent, &child)) pr_warn("%pOF failed to add subdomain: %pOF\n", parent.np, child.np); @@ -163,6 +147,21 @@ static __init int exynos4_pm_init_power_domain(void) parent.np, child.np); } - return 0; + pm_runtime_enable(dev); + return ret; +} + +static struct platform_driver exynos_pd_driver = { + .probe = exynos_pd_probe, + .driver = { + .name = "exynos-pd", + .of_match_table = exynos_pm_domain_of_match, + .suppress_bind_attrs = true, + } +}; + +static __init int exynos4_pm_init_power_domain(void) +{ + return platform_driver_register(&exynos_pd_driver); } core_initcall(exynos4_pm_init_power_domain); diff --git a/drivers/soc/sunxi/sunxi_mbus.c b/drivers/soc/sunxi/sunxi_mbus.c index e9925c8487d7..d90e4a264b6f 100644 --- a/drivers/soc/sunxi/sunxi_mbus.c +++ b/drivers/soc/sunxi/sunxi_mbus.c @@ -23,12 +23,7 @@ static const char * const sunxi_mbus_devices[] = { "allwinner,sun7i-a20-display-engine", "allwinner,sun8i-a23-display-engine", "allwinner,sun8i-a33-display-engine", - "allwinner,sun8i-a83t-display-engine", - "allwinner,sun8i-h3-display-engine", - "allwinner,sun8i-r40-display-engine", - "allwinner,sun8i-v3s-display-engine", "allwinner,sun9i-a80-display-engine", - "allwinner,sun50i-a64-display-engine", /* * And now we have the regular devices connected to the MBUS diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c index 77f0051358f1..bf1468e5bccb 100644 --- a/drivers/soc/ti/omap_prm.c +++ b/drivers/soc/ti/omap_prm.c @@ -860,6 +860,7 @@ static int omap_prm_reset_init(struct platform_device *pdev, const struct omap_rst_map *map; struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev); char buf[32]; + u32 v; /* * Check if we have controllable resets. If either rstctrl is non-zero @@ -907,6 +908,16 @@ static int omap_prm_reset_init(struct platform_device *pdev, map++; } + /* Quirk handling to assert rst_map_012 bits on reset and avoid errors */ + if (prm->data->rstmap == rst_map_012) { + v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl); + if ((v & reset->mask) != reset->mask) { + dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v); + writel_relaxed(reset->mask, reset->prm->base + + reset->prm->data->rstctrl); + } + } + return devm_reset_controller_register(&pdev->dev, &reset->rcdev); } diff --git a/drivers/soc/zte/Kconfig b/drivers/soc/zte/Kconfig deleted file mode 100644 index 1cf1938da541..000000000000 --- a/drivers/soc/zte/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# ZTE SoC drivers -# -menuconfig SOC_ZTE - depends on ARCH_ZX || COMPILE_TEST - 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 deleted file mode 100644 index 728c677addcd..000000000000 --- a/drivers/soc/zte/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# 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 deleted file mode 100644 index 4daab06bbc26..000000000000 --- a/drivers/soc/zte/zx296718_pm_domains.c +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie <baoyou.xie@linaro.org> - */ - -#include <dt-bindings/soc/zte,pm_domains.h> -#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", - .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); diff --git a/drivers/soc/zte/zx2967_pm_domains.c b/drivers/soc/zte/zx2967_pm_domains.c deleted file mode 100644 index a4503e31b616..000000000000 --- a/drivers/soc/zte/zx2967_pm_domains.c +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie <baoyou.xie@linaro.org> - */ - -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/of.h> - -#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)) - 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 deleted file mode 100644 index f586c02410ff..000000000000 --- a/drivers/soc/zte/zx2967_pm_domains.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Header for ZTE's Power Domain Driver support - * - * Copyright (C) 2017 ZTE Ltd. - * - * Author: Baoyou Xie <baoyou.xie@linaro.org> - */ - -#ifndef __ZTE_ZX2967_PM_DOMAIN_H -#define __ZTE_ZX2967_PM_DOMAIN_H - -#include <linux/platform_device.h> -#include <linux/pm_domain.h> - -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 */ |