diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 23:26:56 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 23:26:56 +0400 |
commit | 8793422fd9ac5037f5047f80473007301df3689f (patch) | |
tree | f5aa3b3a564f053e1b5604c45db80193abc734a4 /drivers/clk | |
parent | b3cdda2b4f541439ca4205793040aa2e1c852e3b (diff) | |
parent | 10baf04e95fbf7eb6089410220a547211dd2ffa7 (diff) | |
download | linux-8793422fd9ac5037f5047f80473007301df3689f.tar.xz |
Merge tag 'pm+acpi-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael Wysocki:
- Rework of the ACPI namespace scanning code from Rafael J. Wysocki
with contributions from Bjorn Helgaas, Jiang Liu, Mika Westerberg,
Toshi Kani, and Yinghai Lu.
- ACPI power resources handling and ACPI device PM update from Rafael
J Wysocki.
- ACPICA update to version 20130117 from Bob Moore and Lv Zheng with
contributions from Aaron Lu, Chao Guan, Jesper Juhl, and Tim Gardner.
- Support for Intel Lynxpoint LPSS from Mika Westerberg.
- cpuidle update from Len Brown including Intel Haswell support, C1
state for intel_idle, removal of global pm_idle.
- cpuidle fixes and cleanups from Daniel Lezcano.
- cpufreq fixes and cleanups from Viresh Kumar and Fabio Baltieri with
contributions from Stratos Karafotis and Rickard Andersson.
- Intel P-states driver for Sandy Bridge processors from Dirk
Brandewie.
- cpufreq driver for Marvell Kirkwood SoCs from Andrew Lunn.
- cpufreq fixes related to ordering issues between acpi-cpufreq and
powernow-k8 from Borislav Petkov and Matthew Garrett.
- cpufreq support for Calxeda Highbank processors from Mark Langsdorf
and Rob Herring.
- cpufreq driver for the Freescale i.MX6Q SoC and cpufreq-cpu0 update
from Shawn Guo.
- cpufreq Exynos fixes and cleanups from Jonghwan Choi, Sachin Kamat,
and Inderpal Singh.
- Support for "lightweight suspend" from Zhang Rui.
- Removal of the deprecated power trace API from Paul Gortmaker.
- Assorted updates from Andreas Fleig, Colin Ian King, Davidlohr Bueso,
Joseph Salisbury, Kees Cook, Li Fei, Nishanth Menon, ShuoX Liu,
Srinivas Pandruvada, Tejun Heo, Thomas Renninger, and Yasuaki
Ishimatsu.
* tag 'pm+acpi-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (267 commits)
PM idle: remove global declaration of pm_idle
unicore32 idle: delete stray pm_idle comment
openrisc idle: delete pm_idle
mn10300 idle: delete pm_idle
microblaze idle: delete pm_idle
m32r idle: delete pm_idle, and other dead idle code
ia64 idle: delete pm_idle
cris idle: delete idle and pm_idle
ARM64 idle: delete pm_idle
ARM idle: delete pm_idle
blackfin idle: delete pm_idle
sparc idle: rename pm_idle to sparc_idle
sh idle: rename global pm_idle to static sh_idle
x86 idle: rename global pm_idle to static x86_idle
APM idle: register apm_cpu_idle via cpuidle
cpufreq / intel_pstate: Add kernel command line option disable intel_pstate.
cpufreq / intel_pstate: Change to disallow module build
tools/power turbostat: display SMI count by default
intel_idle: export both C1 and C1E
ACPI / hotplug: Fix concurrency issues and memory leaks
...
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/clk-highbank.c | 2 | ||||
-rw-r--r-- | drivers/clk/mvebu/clk-gating-ctrl.c | 1 | ||||
-rw-r--r-- | drivers/clk/x86/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/x86/clk-lpss.c | 99 | ||||
-rw-r--r-- | drivers/clk/x86/clk-lpss.h | 36 | ||||
-rw-r--r-- | drivers/clk/x86/clk-lpt.c | 86 |
7 files changed, 227 insertions, 0 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 0ad642fbe794..14fde73ea6ff 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o +obj-$(CONFIG_X86) += x86/ # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c index 5d1de2e11753..2e08cb001936 100644 --- a/drivers/clk/clk-highbank.c +++ b/drivers/clk/clk-highbank.c @@ -182,8 +182,10 @@ static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned long rate, reg |= HB_PLL_EXT_ENA; reg &= ~HB_PLL_EXT_BYPASS; } else { + writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg); reg &= ~HB_PLL_DIVQ_MASK; reg |= divq << HB_PLL_DIVQ_SHIFT; + writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg); } writel(reg, hbclk->reg); diff --git a/drivers/clk/mvebu/clk-gating-ctrl.c b/drivers/clk/mvebu/clk-gating-ctrl.c index 8fa5408b6c7d..ebf141d4374b 100644 --- a/drivers/clk/mvebu/clk-gating-ctrl.c +++ b/drivers/clk/mvebu/clk-gating-ctrl.c @@ -193,6 +193,7 @@ static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = { { "runit", NULL, 7 }, { "xor0", NULL, 8 }, { "audio", NULL, 9 }, + { "powersave", "cpuclk", 11 }, { "sata0", NULL, 14 }, { "sata1", NULL, 15 }, { "xor1", NULL, 16 }, diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile new file mode 100644 index 000000000000..f9ba4fab0ddc --- /dev/null +++ b/drivers/clk/x86/Makefile @@ -0,0 +1,2 @@ +clk-x86-lpss-objs := clk-lpss.o clk-lpt.o +obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o diff --git a/drivers/clk/x86/clk-lpss.c b/drivers/clk/x86/clk-lpss.c new file mode 100644 index 000000000000..b5e229f3c3d9 --- /dev/null +++ b/drivers/clk/x86/clk-lpss.c @@ -0,0 +1,99 @@ +/* + * Intel Low Power Subsystem clocks. + * + * Copyright (C) 2013, Intel Corporation + * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> + * Heikki Krogerus <heikki.krogerus@linux.intel.com> + * + * 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/acpi.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> + +static int clk_lpss_is_mmio_resource(struct acpi_resource *res, void *data) +{ + struct resource r; + return !acpi_dev_resource_memory(res, &r); +} + +static acpi_status clk_lpss_find_mmio(acpi_handle handle, u32 level, + void *data, void **retval) +{ + struct resource_list_entry *rentry; + struct list_head resource_list; + struct acpi_device *adev; + const char *uid = data; + int ret; + + if (acpi_bus_get_device(handle, &adev)) + return AE_OK; + + if (uid) { + if (!adev->pnp.unique_id) + return AE_OK; + if (strcmp(uid, adev->pnp.unique_id)) + return AE_OK; + } + + INIT_LIST_HEAD(&resource_list); + ret = acpi_dev_get_resources(adev, &resource_list, + clk_lpss_is_mmio_resource, NULL); + if (ret < 0) + return AE_NO_MEMORY; + + list_for_each_entry(rentry, &resource_list, node) + if (resource_type(&rentry->res) == IORESOURCE_MEM) { + *(struct resource *)retval = rentry->res; + break; + } + + acpi_dev_free_resource_list(&resource_list); + return AE_OK; +} + +/** + * clk_register_lpss_gate - register LPSS clock gate + * @name: name of this clock gate + * @parent_name: parent clock name + * @hid: ACPI _HID of the device + * @uid: ACPI _UID of the device (optional) + * @offset: LPSS PRV_CLOCK_PARAMS offset + * + * Creates and registers LPSS clock gate. + */ +struct clk *clk_register_lpss_gate(const char *name, const char *parent_name, + const char *hid, const char *uid, + unsigned offset) +{ + struct resource res = { }; + void __iomem *mmio_base; + acpi_status status; + struct clk *clk; + + /* + * First try to look the device and its mmio resource from the + * ACPI namespace. + */ + status = acpi_get_devices(hid, clk_lpss_find_mmio, (void *)uid, + (void **)&res); + if (ACPI_FAILURE(status) || !res.start) + return ERR_PTR(-ENODEV); + + mmio_base = ioremap(res.start, resource_size(&res)); + if (!mmio_base) + return ERR_PTR(-ENOMEM); + + clk = clk_register_gate(NULL, name, parent_name, 0, mmio_base + offset, + 0, 0, NULL); + if (IS_ERR(clk)) + iounmap(mmio_base); + + return clk; +} diff --git a/drivers/clk/x86/clk-lpss.h b/drivers/clk/x86/clk-lpss.h new file mode 100644 index 000000000000..e9460f442297 --- /dev/null +++ b/drivers/clk/x86/clk-lpss.h @@ -0,0 +1,36 @@ +/* + * Intel Low Power Subsystem clock. + * + * Copyright (C) 2013, Intel Corporation + * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> + * Heikki Krogerus <heikki.krogerus@linux.intel.com> + * + * 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. + */ + +#ifndef __CLK_LPSS_H +#define __CLK_LPSS_H + +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/clk.h> + +#ifdef CONFIG_ACPI +extern struct clk *clk_register_lpss_gate(const char *name, + const char *parent_name, + const char *hid, const char *uid, + unsigned offset); +#else +static inline struct clk *clk_register_lpss_gate(const char *name, + const char *parent_name, + const char *hid, + const char *uid, + unsigned offset) +{ + return ERR_PTR(-ENODEV); +} +#endif + +#endif /* __CLK_LPSS_H */ diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c new file mode 100644 index 000000000000..81298aeef7e3 --- /dev/null +++ b/drivers/clk/x86/clk-lpt.c @@ -0,0 +1,86 @@ +/* + * Intel Lynxpoint LPSS clocks. + * + * Copyright (C) 2013, Intel Corporation + * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> + * Heikki Krogerus <heikki.krogerus@linux.intel.com> + * + * 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/acpi.h> +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include "clk-lpss.h" + +#define PRV_CLOCK_PARAMS 0x800 + +static int lpt_clk_probe(struct platform_device *pdev) +{ + struct clk *clk; + + /* LPSS free running clock */ + clk = clk_register_fixed_rate(&pdev->dev, "lpss_clk", NULL, CLK_IS_ROOT, + 100000000); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + /* Shared DMA clock */ + clk_register_clkdev(clk, "hclk", "INTL9C60.0.auto"); + + /* SPI clocks */ + clk = clk_register_lpss_gate("spi0_clk", "lpss_clk", "INT33C0", NULL, + PRV_CLOCK_PARAMS); + if (!IS_ERR(clk)) + clk_register_clkdev(clk, NULL, "INT33C0:00"); + + clk = clk_register_lpss_gate("spi1_clk", "lpss_clk", "INT33C1", NULL, + PRV_CLOCK_PARAMS); + if (!IS_ERR(clk)) + clk_register_clkdev(clk, NULL, "INT33C1:00"); + + /* I2C clocks */ + clk = clk_register_lpss_gate("i2c0_clk", "lpss_clk", "INT33C2", NULL, + PRV_CLOCK_PARAMS); + if (!IS_ERR(clk)) + clk_register_clkdev(clk, NULL, "INT33C2:00"); + + clk = clk_register_lpss_gate("i2c1_clk", "lpss_clk", "INT33C3", NULL, + PRV_CLOCK_PARAMS); + if (!IS_ERR(clk)) + clk_register_clkdev(clk, NULL, "INT33C3:00"); + + /* UART clocks */ + clk = clk_register_lpss_gate("uart0_clk", "lpss_clk", "INT33C4", NULL, + PRV_CLOCK_PARAMS); + if (!IS_ERR(clk)) + clk_register_clkdev(clk, NULL, "INT33C4:00"); + + clk = clk_register_lpss_gate("uart1_clk", "lpss_clk", "INT33C5", NULL, + PRV_CLOCK_PARAMS); + if (!IS_ERR(clk)) + clk_register_clkdev(clk, NULL, "INT33C5:00"); + + return 0; +} + +static struct platform_driver lpt_clk_driver = { + .driver = { + .name = "clk-lpt", + .owner = THIS_MODULE, + }, + .probe = lpt_clk_probe, +}; + +static int __init lpt_clk_init(void) +{ + return platform_driver_register(&lpt_clk_driver); +} +arch_initcall(lpt_clk_init); |