diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-20 14:57:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-20 14:57:08 -0700 |
commit | 33b3d2e88c9efd701b6153ca4714d4aa6e9f5af0 (patch) | |
tree | 7a3bf34e08e6c7b32e0d5c9333b02a02e3af6330 /drivers/soc/samsung/exynos-pmu.c | |
parent | e88fa1b8b00a947299e2415e819301fa52037cf4 (diff) | |
parent | 307d40c56b0c86315859ee724b51748260f50e65 (diff) | |
download | op-kernel-dev-33b3d2e88c9efd701b6153ca4714d4aa6e9f5af0.zip op-kernel-dev-33b3d2e88c9efd701b6153ca4714d4aa6e9f5af0.tar.gz |
Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates from Arnd Bergmann:
"Newly added support for additional SoCs:
- Axis Artpec-6 SoC family
- Allwinner A83T SoC
- Mediatek MT7623
- NXP i.MX6QP SoC
- ST Microelectronics stm32f469 microcontroller
New features:
- SMP support for Mediatek mt2701
- Big-endian support for NXP i.MX
- DaVinci now uses the new DMA engine dma_slave_map
- OMAP now uses the new DMA engine dma_slave_map
- earlyprintk support for palmchip uart on mach-tango
- delay timer support for orion
Other:
- Exynos PMU driver moved out to drivers/soc/
- Various smaller updates for Renesas, Xilinx, PXA, AT91, OMAP,
uniphier"
* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (83 commits)
ARM: uniphier: rework SMP code to support new System Bus binding
ARM: uniphier: add missing of_node_put()
ARM: at91: avoid defining CONFIG_* symbols in source code
ARM: DRA7: hwmod: Add data for eDMA tpcc, tptc0, tptc1
ARM: imx: Make reset_control_ops const
ARM: imx: Do L2 errata only if the L2 cache isn't enabled
ARM: imx: select ARM_CPU_SUSPEND only for imx6
dmaengine: pxa_dma: fix the maximum requestor line
ARM: alpine: select the Alpine MSI controller driver
ARM: pxa: add the number of DMA requestor lines
dmaengine: mmp-pdma: add number of requestors
dma: mmp_pdma: Add the #dma-requests DT property documentation
ARM: OMAP2+: Add rtc hwmod configuration for ti81xx
ARM: s3c24xx: Avoid warning for inb/outb
ARM: zynq: Move early printk virtual address to vmalloc area
ARM: DRA7: hwmod: Add custom reset handler for PCIeSS
ARM: SAMSUNG: Remove unused register offset definition
ARM: EXYNOS: Cleanup header files inclusion
drivers: soc: samsung: Enable COMPILE_TEST
MAINTAINERS: Add maintainers entry for drivers/soc/samsung
...
Diffstat (limited to 'drivers/soc/samsung/exynos-pmu.c')
-rw-r--r-- | drivers/soc/samsung/exynos-pmu.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c new file mode 100644 index 0000000..0acdfd8 --- /dev/null +++ b/drivers/soc/samsung/exynos-pmu.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * EXYNOS - CPU PMU(Power Management Unit) support + * + * 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 <linux/of.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/delay.h> + +#include <linux/soc/samsung/exynos-regs-pmu.h> +#include <linux/soc/samsung/exynos-pmu.h> + +#include "exynos-pmu.h" + +struct exynos_pmu_context { + struct device *dev; + const struct exynos_pmu_data *pmu_data; +}; + +void __iomem *pmu_base_addr; +static struct exynos_pmu_context *pmu_context; + +void pmu_raw_writel(u32 val, u32 offset) +{ + writel_relaxed(val, pmu_base_addr + offset); +} + +u32 pmu_raw_readl(u32 offset) +{ + return readl_relaxed(pmu_base_addr + offset); +} + +void exynos_sys_powerdown_conf(enum sys_powerdown mode) +{ + unsigned int i; + const struct exynos_pmu_data *pmu_data; + + if (!pmu_context) + return; + + pmu_data = pmu_context->pmu_data; + + if (pmu_data->powerdown_conf) + pmu_data->powerdown_conf(mode); + + if (pmu_data->pmu_config) { + for (i = 0; (pmu_data->pmu_config[i].offset != PMU_TABLE_END); i++) + pmu_raw_writel(pmu_data->pmu_config[i].val[mode], + pmu_data->pmu_config[i].offset); + } + + if (pmu_data->powerdown_conf_extra) + pmu_data->powerdown_conf_extra(mode); + + if (pmu_data->pmu_config_extra) { + for (i = 0; pmu_data->pmu_config_extra[i].offset != PMU_TABLE_END; i++) + pmu_raw_writel(pmu_data->pmu_config_extra[i].val[mode], + pmu_data->pmu_config_extra[i].offset); + } +} + +/* + * PMU platform driver and devicetree bindings. + */ +static const struct of_device_id exynos_pmu_of_device_ids[] = { + { + .compatible = "samsung,exynos3250-pmu", + .data = &exynos3250_pmu_data, + }, { + .compatible = "samsung,exynos4210-pmu", + .data = &exynos4210_pmu_data, + }, { + .compatible = "samsung,exynos4212-pmu", + .data = &exynos4212_pmu_data, + }, { + .compatible = "samsung,exynos4412-pmu", + .data = &exynos4412_pmu_data, + }, { + .compatible = "samsung,exynos5250-pmu", + .data = &exynos5250_pmu_data, + }, { + .compatible = "samsung,exynos5420-pmu", + .data = &exynos5420_pmu_data, + }, + { /*sentinel*/ }, +}; + +static int exynos_pmu_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + struct device *dev = &pdev->dev; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pmu_base_addr = devm_ioremap_resource(dev, res); + if (IS_ERR(pmu_base_addr)) + return PTR_ERR(pmu_base_addr); + + pmu_context = devm_kzalloc(&pdev->dev, + sizeof(struct exynos_pmu_context), + GFP_KERNEL); + if (!pmu_context) { + dev_err(dev, "Cannot allocate memory.\n"); + return -ENOMEM; + } + pmu_context->dev = dev; + + match = of_match_node(exynos_pmu_of_device_ids, dev->of_node); + + pmu_context->pmu_data = match->data; + + if (pmu_context->pmu_data->pmu_init) + pmu_context->pmu_data->pmu_init(); + + platform_set_drvdata(pdev, pmu_context); + + dev_dbg(dev, "Exynos PMU Driver probe done\n"); + return 0; +} + +static struct platform_driver exynos_pmu_driver = { + .driver = { + .name = "exynos-pmu", + .of_match_table = exynos_pmu_of_device_ids, + }, + .probe = exynos_pmu_probe, +}; + +static int __init exynos_pmu_init(void) +{ + return platform_driver_register(&exynos_pmu_driver); + +} +postcore_initcall(exynos_pmu_init); |