diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 11:26:56 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 11:26:56 -0800 |
commit | 8793422fd9ac5037f5047f80473007301df3689f (patch) | |
tree | f5aa3b3a564f053e1b5604c45db80193abc734a4 /drivers/acpi/csrt.c | |
parent | b3cdda2b4f541439ca4205793040aa2e1c852e3b (diff) | |
parent | 10baf04e95fbf7eb6089410220a547211dd2ffa7 (diff) |
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/acpi/csrt.c')
-rw-r--r-- | drivers/acpi/csrt.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/drivers/acpi/csrt.c b/drivers/acpi/csrt.c new file mode 100644 index 000000000000..5c15a91faf0b --- /dev/null +++ b/drivers/acpi/csrt.c @@ -0,0 +1,159 @@ +/* + * Support for Core System Resources Table (CSRT) + * + * Copyright (C) 2013, Intel Corporation + * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> + * Andy Shevchenko <andriy.shevchenko@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. + */ + +#define pr_fmt(fmt) "ACPI: CSRT: " fmt + +#include <linux/acpi.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/sizes.h> + +ACPI_MODULE_NAME("CSRT"); + +static int __init acpi_csrt_parse_shared_info(struct platform_device *pdev, + const struct acpi_csrt_group *grp) +{ + const struct acpi_csrt_shared_info *si; + struct resource res[3]; + size_t nres; + int ret; + + memset(res, 0, sizeof(res)); + nres = 0; + + si = (const struct acpi_csrt_shared_info *)&grp[1]; + /* + * The peripherals that are listed on CSRT typically support only + * 32-bit addresses so we only use the low part of MMIO base for + * now. + */ + if (!si->mmio_base_high && si->mmio_base_low) { + /* + * There is no size of the memory resource in shared_info + * so we assume that it is 4k here. + */ + res[nres].start = si->mmio_base_low; + res[nres].end = res[0].start + SZ_4K - 1; + res[nres++].flags = IORESOURCE_MEM; + } + + if (si->gsi_interrupt) { + int irq = acpi_register_gsi(NULL, si->gsi_interrupt, + si->interrupt_mode, + si->interrupt_polarity); + res[nres].start = irq; + res[nres].end = irq; + res[nres++].flags = IORESOURCE_IRQ; + } + + if (si->base_request_line || si->num_handshake_signals) { + /* + * We pass the driver a DMA resource describing the range + * of request lines the device supports. + */ + res[nres].start = si->base_request_line; + res[nres].end = res[nres].start + si->num_handshake_signals - 1; + res[nres++].flags = IORESOURCE_DMA; + } + + ret = platform_device_add_resources(pdev, res, nres); + if (ret) { + if (si->gsi_interrupt) + acpi_unregister_gsi(si->gsi_interrupt); + return ret; + } + + return 0; +} + +static int __init +acpi_csrt_parse_resource_group(const struct acpi_csrt_group *grp) +{ + struct platform_device *pdev; + char vendor[5], name[16]; + int ret, i; + + vendor[0] = grp->vendor_id; + vendor[1] = grp->vendor_id >> 8; + vendor[2] = grp->vendor_id >> 16; + vendor[3] = grp->vendor_id >> 24; + vendor[4] = '\0'; + + if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info)) + return -ENODEV; + + snprintf(name, sizeof(name), "%s%04X", vendor, grp->device_id); + pdev = platform_device_alloc(name, PLATFORM_DEVID_AUTO); + if (!pdev) + return -ENOMEM; + + /* Add resources based on the shared info */ + ret = acpi_csrt_parse_shared_info(pdev, grp); + if (ret) + goto fail; + + ret = platform_device_add(pdev); + if (ret) + goto fail; + + for (i = 0; i < pdev->num_resources; i++) + dev_dbg(&pdev->dev, "%pR\n", &pdev->resource[i]); + + return 0; + +fail: + platform_device_put(pdev); + return ret; +} + +/* + * CSRT or Core System Resources Table is a proprietary ACPI table + * introduced by Microsoft. This table can contain devices that are not in + * the system DSDT table. In particular DMA controllers might be described + * here. + * + * We present these devices as normal platform devices that don't have ACPI + * IDs or handle. The platform device name will be something like + * <VENDOR><DEVID>.<n>.auto for example: INTL9C06.0.auto. + */ +void __init acpi_csrt_init(void) +{ + struct acpi_csrt_group *grp, *end; + struct acpi_table_csrt *csrt; + acpi_status status; + int ret; + + status = acpi_get_table(ACPI_SIG_CSRT, 0, + (struct acpi_table_header **)&csrt); + if (ACPI_FAILURE(status)) { + if (status != AE_NOT_FOUND) + pr_warn("failed to get the CSRT table\n"); + return; + } + + pr_debug("parsing CSRT table for devices\n"); + + grp = (struct acpi_csrt_group *)(csrt + 1); + end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length); + + while (grp < end) { + ret = acpi_csrt_parse_resource_group(grp); + if (ret) { + pr_warn("error in parsing resource group: %d\n", ret); + return; + } + + grp = (struct acpi_csrt_group *)((void *)grp + grp->length); + } +} |