aboutsummaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Makefile7
-rw-r--r--drivers/acpi/acpi_cmos_rtc.c2
-rw-r--r--drivers/acpi/acpi_extlog.c16
-rw-r--r--drivers/acpi/acpi_lpss.c309
-rw-r--r--drivers/acpi/acpi_memhotplug.c31
-rw-r--r--drivers/acpi/acpi_pad.c16
-rw-r--r--drivers/acpi/acpi_platform.c51
-rw-r--r--drivers/acpi/acpi_pnp.c395
-rw-r--r--drivers/acpi/acpi_processor.c2
-rw-r--r--drivers/acpi/acpica/Makefile1
-rw-r--r--drivers/acpi/acpica/acapps.h170
-rw-r--r--drivers/acpi/acpica/acevents.h5
-rw-r--r--drivers/acpi/acpica/acglobal.h142
-rw-r--r--drivers/acpi/acpica/aclocal.h17
-rw-r--r--drivers/acpi/acpica/acpredef.h10
-rw-r--r--drivers/acpi/acpica/actables.h62
-rw-r--r--drivers/acpi/acpica/acutils.h10
-rw-r--r--drivers/acpi/acpica/evgpe.c13
-rw-r--r--drivers/acpi/acpica/evgpeblk.c34
-rw-r--r--drivers/acpi/acpica/evgpeinit.c12
-rw-r--r--drivers/acpi/acpica/evmisc.c3
-rw-r--r--drivers/acpi/acpica/evsci.c2
-rw-r--r--drivers/acpi/acpica/evxface.c61
-rw-r--r--drivers/acpi/acpica/evxfgpe.c7
-rw-r--r--drivers/acpi/acpica/exconfig.c82
-rw-r--r--drivers/acpi/acpica/exdump.c4
-rw-r--r--drivers/acpi/acpica/hwpci.c15
-rw-r--r--drivers/acpi/acpica/rscreate.c13
-rw-r--r--drivers/acpi/acpica/tbdata.c760
-rw-r--r--drivers/acpi/acpica/tbfadt.c61
-rw-r--r--drivers/acpi/acpica/tbfind.c4
-rw-r--r--drivers/acpi/acpica/tbinstal.c837
-rw-r--r--drivers/acpi/acpica/tbutils.c285
-rw-r--r--drivers/acpi/acpica/tbxface.c18
-rw-r--r--drivers/acpi/acpica/tbxfload.c87
-rw-r--r--drivers/acpi/acpica/utdecode.c74
-rw-r--r--drivers/acpi/acpica/utglobal.c26
-rw-r--r--drivers/acpi/acpica/utstring.c2
-rw-r--r--drivers/acpi/acpica/utxferror.c2
-rw-r--r--drivers/acpi/apei/einj.c14
-rw-r--r--drivers/acpi/battery.c77
-rw-r--r--drivers/acpi/bus.c56
-rw-r--r--drivers/acpi/container.c15
-rw-r--r--drivers/acpi/device_pm.c46
-rw-r--r--drivers/acpi/internal.h18
-rw-r--r--drivers/acpi/nvs.c4
-rw-r--r--drivers/acpi/osl.c32
-rw-r--r--drivers/acpi/processor_driver.c7
-rw-r--r--drivers/acpi/scan.c76
-rw-r--r--drivers/acpi/sleep.c19
-rw-r--r--drivers/acpi/tables.c23
-rw-r--r--drivers/acpi/thermal.c11
-rw-r--r--drivers/acpi/utils.c64
-rw-r--r--drivers/acpi/video.c252
54 files changed, 2940 insertions, 1422 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index bce34afadcd..ea55e0179f8 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -39,8 +39,9 @@ acpi-y += processor_core.o
acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o
acpi-y += pci_root.o pci_link.o pci_irq.o
-acpi-$(CONFIG_X86_INTEL_LPSS) += acpi_lpss.o
+acpi-y += acpi_lpss.o
acpi-y += acpi_platform.o
+acpi-y += acpi_pnp.o
acpi-y += power.o
acpi-y += event.o
acpi-y += sysfs.o
@@ -63,9 +64,9 @@ obj-$(CONFIG_ACPI_FAN) += fan.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
-obj-$(CONFIG_ACPI_CONTAINER) += container.o
+obj-y += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
-obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
+obj-y += acpi_memhotplug.o
obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_SBS) += sbshc.o
obj-$(CONFIG_ACPI_SBS) += sbs.o
diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c
index 961b45d18a5..2da8660262e 100644
--- a/drivers/acpi/acpi_cmos_rtc.c
+++ b/drivers/acpi/acpi_cmos_rtc.c
@@ -68,7 +68,7 @@ static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
return -ENODEV;
}
- return 0;
+ return 1;
}
static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index c4a5d87ede7..185334114d7 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -220,13 +220,13 @@ static int __init extlog_init(void)
goto err;
}
- extlog_l1_hdr = acpi_os_map_memory(l1_dirbase, l1_hdr_size);
+ extlog_l1_hdr = acpi_os_map_iomem(l1_dirbase, l1_hdr_size);
l1_head = (struct extlog_l1_head *)extlog_l1_hdr;
l1_size = l1_head->total_len;
l1_percpu_entry = l1_head->entries;
elog_base = l1_head->elog_base;
elog_size = l1_head->elog_len;
- acpi_os_unmap_memory(extlog_l1_hdr, l1_hdr_size);
+ acpi_os_unmap_iomem(extlog_l1_hdr, l1_hdr_size);
release_mem_region(l1_dirbase, l1_hdr_size);
/* remap L1 header again based on completed information */
@@ -237,7 +237,7 @@ static int __init extlog_init(void)
(unsigned long long)l1_dirbase + l1_size);
goto err;
}
- extlog_l1_addr = acpi_os_map_memory(l1_dirbase, l1_size);
+ extlog_l1_addr = acpi_os_map_iomem(l1_dirbase, l1_size);
l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size);
/* remap elog table */
@@ -248,7 +248,7 @@ static int __init extlog_init(void)
(unsigned long long)elog_base + elog_size);
goto err_release_l1_dir;
}
- elog_addr = acpi_os_map_memory(elog_base, elog_size);
+ elog_addr = acpi_os_map_iomem(elog_base, elog_size);
rc = -ENOMEM;
/* allocate buffer to save elog record */
@@ -270,11 +270,11 @@ static int __init extlog_init(void)
err_release_elog:
if (elog_addr)
- acpi_os_unmap_memory(elog_addr, elog_size);
+ acpi_os_unmap_iomem(elog_addr, elog_size);
release_mem_region(elog_base, elog_size);
err_release_l1_dir:
if (extlog_l1_addr)
- acpi_os_unmap_memory(extlog_l1_addr, l1_size);
+ acpi_os_unmap_iomem(extlog_l1_addr, l1_size);
release_mem_region(l1_dirbase, l1_size);
err:
pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n");
@@ -287,9 +287,9 @@ static void __exit extlog_exit(void)
mce_unregister_decode_chain(&extlog_mce_dec);
((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
if (extlog_l1_addr)
- acpi_os_unmap_memory(extlog_l1_addr, l1_size);
+ acpi_os_unmap_iomem(extlog_l1_addr, l1_size);
if (elog_addr)
- acpi_os_unmap_memory(elog_addr, elog_size);
+ acpi_os_unmap_iomem(elog_addr, elog_size);
release_mem_region(elog_base, elog_size);
release_mem_region(l1_dirbase, l1_size);
kfree(elog_buf);
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 69e29f409d4..63407d26488 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -19,15 +19,21 @@
#include <linux/platform_device.h>
#include <linux/platform_data/clk-lpss.h>
#include <linux/pm_runtime.h>
+#include <linux/delay.h>
#include "internal.h"
ACPI_MODULE_NAME("acpi_lpss");
+#ifdef CONFIG_X86_INTEL_LPSS
+
+#define LPSS_ADDR(desc) ((unsigned long)&desc)
+
#define LPSS_CLK_SIZE 0x04
#define LPSS_LTR_SIZE 0x18
/* Offsets relative to LPSS_PRIVATE_OFFSET */
+#define LPSS_CLK_DIVIDER_DEF_MASK (BIT(1) | BIT(16))
#define LPSS_GENERAL 0x08
#define LPSS_GENERAL_LTR_MODE_SW BIT(2)
#define LPSS_GENERAL_UART_RTS_OVRD BIT(3)
@@ -43,6 +49,8 @@ ACPI_MODULE_NAME("acpi_lpss");
#define LPSS_TX_INT 0x20
#define LPSS_TX_INT_MASK BIT(1)
+#define LPSS_PRV_REG_COUNT 9
+
struct lpss_shared_clock {
const char *name;
unsigned long rate;
@@ -57,7 +65,9 @@ struct lpss_device_desc {
bool ltr_required;
unsigned int prv_offset;
size_t prv_size_override;
+ bool clk_divider;
bool clk_gate;
+ bool save_ctx;
struct lpss_shared_clock *shared_clock;
void (*setup)(struct lpss_private_data *pdata);
};
@@ -72,6 +82,7 @@ struct lpss_private_data {
resource_size_t mmio_size;
struct clk *clk;
const struct lpss_device_desc *dev_desc;
+ u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
};
static void lpss_uart_setup(struct lpss_private_data *pdata)
@@ -92,6 +103,14 @@ static struct lpss_device_desc lpt_dev_desc = {
.clk_required = true,
.prv_offset = 0x800,
.ltr_required = true,
+ .clk_divider = true,
+ .clk_gate = true,
+};
+
+static struct lpss_device_desc lpt_i2c_dev_desc = {
+ .clk_required = true,
+ .prv_offset = 0x800,
+ .ltr_required = true,
.clk_gate = true,
};
@@ -99,6 +118,7 @@ static struct lpss_device_desc lpt_uart_dev_desc = {
.clk_required = true,
.prv_offset = 0x800,
.ltr_required = true,
+ .clk_divider = true,
.clk_gate = true,
.setup = lpss_uart_setup,
};
@@ -116,32 +136,25 @@ static struct lpss_shared_clock pwm_clock = {
static struct lpss_device_desc byt_pwm_dev_desc = {
.clk_required = true,
+ .save_ctx = true,
.shared_clock = &pwm_clock,
};
-static struct lpss_shared_clock uart_clock = {
- .name = "uart_clk",
- .rate = 44236800,
-};
-
static struct lpss_device_desc byt_uart_dev_desc = {
.clk_required = true,
.prv_offset = 0x800,
+ .clk_divider = true,
.clk_gate = true,
- .shared_clock = &uart_clock,
+ .save_ctx = true,
.setup = lpss_uart_setup,
};
-static struct lpss_shared_clock spi_clock = {
- .name = "spi_clk",
- .rate = 50000000,
-};
-
static struct lpss_device_desc byt_spi_dev_desc = {
.clk_required = true,
.prv_offset = 0x400,
+ .clk_divider = true,
.clk_gate = true,
- .shared_clock = &spi_clock,
+ .save_ctx = true,
};
static struct lpss_device_desc byt_sdio_dev_desc = {
@@ -156,43 +169,53 @@ static struct lpss_shared_clock i2c_clock = {
static struct lpss_device_desc byt_i2c_dev_desc = {
.clk_required = true,
.prv_offset = 0x800,
+ .save_ctx = true,
.shared_clock = &i2c_clock,
};
+#else
+
+#define LPSS_ADDR(desc) (0UL)
+
+#endif /* CONFIG_X86_INTEL_LPSS */
+
static const struct acpi_device_id acpi_lpss_device_ids[] = {
/* Generic LPSS devices */
- { "INTL9C60", (unsigned long)&lpss_dma_desc },
+ { "INTL9C60", LPSS_ADDR(lpss_dma_desc) },
/* Lynxpoint LPSS devices */
- { "INT33C0", (unsigned long)&lpt_dev_desc },
- { "INT33C1", (unsigned long)&lpt_dev_desc },
- { "INT33C2", (unsigned long)&lpt_dev_desc },
- { "INT33C3", (unsigned long)&lpt_dev_desc },
- { "INT33C4", (unsigned long)&lpt_uart_dev_desc },
- { "INT33C5", (unsigned long)&lpt_uart_dev_desc },
- { "INT33C6", (unsigned long)&lpt_sdio_dev_desc },
+ { "INT33C0", LPSS_ADDR(lpt_dev_desc) },
+ { "INT33C1", LPSS_ADDR(lpt_dev_desc) },
+ { "INT33C2", LPSS_ADDR(lpt_i2c_dev_desc) },
+ { "INT33C3", LPSS_ADDR(lpt_i2c_dev_desc) },
+ { "INT33C4", LPSS_ADDR(lpt_uart_dev_desc) },
+ { "INT33C5", LPSS_ADDR(lpt_uart_dev_desc) },
+ { "INT33C6", LPSS_ADDR(lpt_sdio_dev_desc) },
{ "INT33C7", },
/* BayTrail LPSS devices */
- { "80860F09", (unsigned long)&byt_pwm_dev_desc },
- { "80860F0A", (unsigned long)&byt_uart_dev_desc },
- { "80860F0E", (unsigned long)&byt_spi_dev_desc },
- { "80860F14", (unsigned long)&byt_sdio_dev_desc },
- { "80860F41", (unsigned long)&byt_i2c_dev_desc },
+ { "80860F09", LPSS_ADDR(byt_pwm_dev_desc) },
+ { "80860F0A", LPSS_ADDR(byt_uart_dev_desc) },
+ { "80860F0E", LPSS_ADDR(byt_spi_dev_desc) },
+ { "80860F14", LPSS_ADDR(byt_sdio_dev_desc) },
+ { "80860F41", LPSS_ADDR(byt_i2c_dev_desc) },
{ "INT33B2", },
-
- { "INT3430", (unsigned long)&lpt_dev_desc },
- { "INT3431", (unsigned long)&lpt_dev_desc },
- { "INT3432", (unsigned long)&lpt_dev_desc },
- { "INT3433", (unsigned long)&lpt_dev_desc },
- { "INT3434", (unsigned long)&lpt_uart_dev_desc },
- { "INT3435", (unsigned long)&lpt_uart_dev_desc },
- { "INT3436", (unsigned long)&lpt_sdio_dev_desc },
+ { "INT33FC", },
+
+ { "INT3430", LPSS_ADDR(lpt_dev_desc) },
+ { "INT3431", LPSS_ADDR(lpt_dev_desc) },
+ { "INT3432", LPSS_ADDR(lpt_i2c_dev_desc) },
+ { "INT3433", LPSS_ADDR(lpt_i2c_dev_desc) },
+ { "INT3434", LPSS_ADDR(lpt_uart_dev_desc) },
+ { "INT3435", LPSS_ADDR(lpt_uart_dev_desc) },
+ { "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) },
{ "INT3437", },
{ }
};
+#ifdef CONFIG_X86_INTEL_LPSS
+
static int is_memory(struct acpi_resource *res, void *not_used)
{
struct resource r;
@@ -212,9 +235,11 @@ static int register_device_clock(struct acpi_device *adev,
{
const struct lpss_device_desc *dev_desc = pdata->dev_desc;
struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
+ const char *devname = dev_name(&adev->dev);
struct clk *clk = ERR_PTR(-ENODEV);
struct lpss_clk_data *clk_data;
- const char *parent;
+ const char *parent, *clk_name;
+ void __iomem *prv_base;
if (!lpss_clk_dev)
lpt_register_clock_device();
@@ -225,7 +250,7 @@ static int register_device_clock(struct acpi_device *adev,
if (dev_desc->clkdev_name) {
clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name,
- dev_name(&adev->dev));
+ devname);
return 0;
}
@@ -234,6 +259,7 @@ static int register_device_clock(struct acpi_device *adev,
return -ENODATA;
parent = clk_data->name;
+ prv_base = pdata->mmio_base + dev_desc->prv_offset;
if (shared_clock) {
clk = shared_clock->clk;
@@ -247,16 +273,41 @@ static int register_device_clock(struct acpi_device *adev,
}
if (dev_desc->clk_gate) {
- clk = clk_register_gate(NULL, dev_name(&adev->dev), parent, 0,
- pdata->mmio_base + dev_desc->prv_offset,
- 0, 0, NULL);
- pdata->clk = clk;
+ clk = clk_register_gate(NULL, devname, parent, 0,
+ prv_base, 0, 0, NULL);
+ parent = devname;
+ }
+
+ if (dev_desc->clk_divider) {
+ /* Prevent division by zero */
+ if (!readl(prv_base))
+ writel(LPSS_CLK_DIVIDER_DEF_MASK, prv_base);
+
+ clk_name = kasprintf(GFP_KERNEL, "%s-div", devname);
+ if (!clk_name)
+ return -ENOMEM;
+ clk = clk_register_fractional_divider(NULL, clk_name, parent,
+ 0, prv_base,
+ 1, 15, 16, 15, 0, NULL);
+ parent = clk_name;
+
+ clk_name = kasprintf(GFP_KERNEL, "%s-update", devname);
+ if (!clk_name) {
+ kfree(parent);
+ return -ENOMEM;
+ }
+ clk = clk_register_gate(NULL, clk_name, parent,
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
+ prv_base, 31, 0, NULL);
+ kfree(parent);
+ kfree(clk_name);
}
if (IS_ERR(clk))
return PTR_ERR(clk);
- clk_register_clkdev(clk, NULL, dev_name(&adev->dev));
+ pdata->clk = clk;
+ clk_register_clkdev(clk, NULL, devname);
return 0;
}
@@ -267,12 +318,14 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
struct lpss_private_data *pdata;
struct resource_list_entry *rentry;
struct list_head resource_list;
+ struct platform_device *pdev;
int ret;
dev_desc = (struct lpss_device_desc *)id->driver_data;
- if (!dev_desc)
- return acpi_create_platform_device(adev, id);
-
+ if (!dev_desc) {
+ pdev = acpi_create_platform_device(adev);
+ return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1;
+ }
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
@@ -322,10 +375,13 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
dev_desc->setup(pdata);
adev->driver_data = pdata;
- ret = acpi_create_platform_device(adev, id);
- if (ret > 0)
- return ret;
+ pdev = acpi_create_platform_device(adev);
+ if (!IS_ERR_OR_NULL(pdev)) {
+ device_enable_async_suspend(&pdev->dev);
+ return 1;
+ }
+ ret = PTR_ERR(pdev);
adev->driver_data = NULL;
err_out:
@@ -449,6 +505,126 @@ static void acpi_lpss_set_ltr(struct device *dev, s32 val)
}
}
+#ifdef CONFIG_PM
+/**
+ * acpi_lpss_save_ctx() - Save the private registers of LPSS device
+ * @dev: LPSS device
+ *
+ * Most LPSS devices have private registers which may loose their context when
+ * the device is powered down. acpi_lpss_save_ctx() saves those registers into
+ * prv_reg_ctx array.
+ */
+static void acpi_lpss_save_ctx(struct device *dev)
+{
+ struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
+ unsigned int i;
+
+ for (i = 0; i < LPSS_PRV_REG_COUNT; i++) {
+ unsigned long offset = i * sizeof(u32);
+
+ pdata->prv_reg_ctx[i] = __lpss_reg_read(pdata, offset);
+ dev_dbg(dev, "saving 0x%08x from LPSS reg at offset 0x%02lx\n",
+ pdata->prv_reg_ctx[i], offset);
+ }
+}
+
+/**
+ * acpi_lpss_restore_ctx() - Restore the private registers of LPSS device
+ * @dev: LPSS device
+ *
+ * Restores the registers that were previously stored with acpi_lpss_save_ctx().
+ */
+static void acpi_lpss_restore_ctx(struct device *dev)
+{
+ struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
+ unsigned int i;
+
+ /*
+ * The following delay is needed or the subsequent write operations may
+ * fail. The LPSS devices are actually PCI devices and the PCI spec
+ * expects 10ms delay before the device can be accessed after D3 to D0
+ * transition.
+ */
+ msleep(10);
+
+ for (i = 0; i < LPSS_PRV_REG_COUNT; i++) {
+ unsigned long offset = i * sizeof(u32);
+
+ __lpss_reg_write(pdata->prv_reg_ctx[i], pdata, offset);
+ dev_dbg(dev, "restoring 0x%08x to LPSS reg at offset 0x%02lx\n",
+ pdata->prv_reg_ctx[i], offset);
+ }
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int acpi_lpss_suspend_late(struct device *dev)
+{
+ int ret = pm_generic_suspend_late(dev);
+
+ if (ret)
+ return ret;
+
+ acpi_lpss_save_ctx(dev);
+ return acpi_dev_suspend_late(dev);
+}
+
+static int acpi_lpss_restore_early(struct device *dev)
+{
+ int ret = acpi_dev_resume_early(dev);
+
+ if (ret)
+ return ret;
+
+ acpi_lpss_restore_ctx(dev);
+ return pm_generic_resume_early(dev);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM_RUNTIME
+static int acpi_lpss_runtime_suspend(struct device *dev)
+{
+ int ret = pm_generic_runtime_suspend(dev);
+
+ if (ret)
+ return ret;
+
+ acpi_lpss_save_ctx(dev);
+ return acpi_dev_runtime_suspend(dev);
+}
+
+static int acpi_lpss_runtime_resume(struct device *dev)
+{
+ int ret = acpi_dev_runtime_resume(dev);
+
+ if (ret)
+ return ret;
+
+ acpi_lpss_restore_ctx(dev);
+ return pm_generic_runtime_resume(dev);
+}
+#endif /* CONFIG_PM_RUNTIME */
+#endif /* CONFIG_PM */
+
+static struct dev_pm_domain acpi_lpss_pm_domain = {
+ .ops = {
+#ifdef CONFIG_PM_SLEEP
+ .suspend_late = acpi_lpss_suspend_late,
+ .restore_early = acpi_lpss_restore_early,
+ .prepare = acpi_subsys_prepare,
+ .complete = acpi_subsys_complete,
+ .suspend = acpi_subsys_suspend,
+ .resume_early = acpi_subsys_resume_early,
+ .freeze = acpi_subsys_freeze,
+ .poweroff = acpi_subsys_suspend,
+ .poweroff_late = acpi_subsys_suspend_late,
+#endif
+#ifdef CONFIG_PM_RUNTIME
+ .runtime_suspend = acpi_lpss_runtime_suspend,
+ .runtime_resume = acpi_lpss_runtime_resume,
+#endif
+ },
+};
+
static int acpi_lpss_platform_notify(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -456,7 +632,6 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
struct lpss_private_data *pdata;
struct acpi_device *adev;
const struct acpi_device_id *id;
- int ret = 0;
id = acpi_match_device(acpi_lpss_device_ids, &pdev->dev);
if (!id || !id->driver_data)
@@ -466,7 +641,7 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
return 0;
pdata = acpi_driver_data(adev);
- if (!pdata || !pdata->mmio_base || !pdata->dev_desc->ltr_required)
+ if (!pdata || !pdata->mmio_base)
return 0;
if (pdata->mmio_size < pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) {
@@ -474,12 +649,27 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb,
return 0;
}
- if (action == BUS_NOTIFY_ADD_DEVICE)
- ret = sysfs_create_group(&pdev->dev.kobj, &lpss_attr_group);
- else if (action == BUS_NOTIFY_DEL_DEVICE)
- sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
+ switch (action) {
+ case BUS_NOTIFY_BOUND_DRIVER:
+ if (pdata->dev_desc->save_ctx)
+ pdev->dev.pm_domain = &acpi_lpss_pm_domain;
+ break;
+ case BUS_NOTIFY_UNBOUND_DRIVER:
+ if (pdata->dev_desc->save_ctx)
+ pdev->dev.pm_domain = NULL;
+ break;
+ case BUS_NOTIFY_ADD_DEVICE:
+ if (pdata->dev_desc->ltr_required)
+ return sysfs_create_group(&pdev->dev.kobj,
+ &lpss_attr_group);
+ case BUS_NOTIFY_DEL_DEVICE:
+ if (pdata->dev_desc->ltr_required)
+ sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
+ default:
+ break;
+ }
- return ret;
+ return 0;
}
static struct notifier_block acpi_lpss_nb = {
@@ -518,3 +708,16 @@ void __init acpi_lpss_init(void)
acpi_scan_add_handler(&lpss_handler);
}
}
+
+#else
+
+static struct acpi_scan_handler lpss_handler = {
+ .ids = acpi_lpss_device_ids,
+};
+
+void __init acpi_lpss_init(void)
+{
+ acpi_scan_add_handler(&lpss_handler);
+}
+
+#endif /* CONFIG_X86_INTEL_LPSS */
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index b67be85ff0f..23e2319ead4 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -44,6 +44,13 @@
ACPI_MODULE_NAME("acpi_memhotplug");
+static const struct acpi_device_id memory_device_ids[] = {
+ {ACPI_MEMORY_DEVICE_HID, 0},
+ {"", 0},
+};
+
+#ifdef CONFIG_ACPI_HOTPLUG_MEMORY
+
/* Memory Device States */
#define MEMORY_INVALID_STATE 0
#define MEMORY_POWER_ON_STATE 1
@@ -53,11 +60,6 @@ static int acpi_memory_device_add(struct acpi_device *device,
const struct acpi_device_id *not_used);
static void acpi_memory_device_remove(struct acpi_device *device);
-static const struct acpi_device_id memory_device_ids[] = {
- {ACPI_MEMORY_DEVICE_HID, 0},
- {"", 0},
-};
-
static struct acpi_scan_handler memory_device_handler = {
.ids = memory_device_ids,
.attach = acpi_memory_device_add,
@@ -364,9 +366,11 @@ static bool __initdata acpi_no_memhotplug;
void __init acpi_memory_hotplug_init(void)
{
- if (acpi_no_memhotplug)
+ if (acpi_no_memhotplug) {
+ memory_device_handler.attach = NULL;
+ acpi_scan_add_handler(&memory_device_handler);
return;
-
+ }
acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory");
}
@@ -376,3 +380,16 @@ static int __init disable_acpi_memory_hotplug(char *str)
return 1;
}
__setup("acpi_no_memhotplug", disable_acpi_memory_hotplug);
+
+#else
+
+static struct acpi_scan_handler memory_device_handler = {
+ .ids = memory_device_ids,
+};
+
+void __init acpi_memory_hotplug_init(void)
+{
+ acpi_scan_add_handler(&memory_device_handler);
+}
+
+#endif /* CONFIG_ACPI_HOTPLUG_MEMORY */
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 37d73024b82..f148a0580e0 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -156,12 +156,13 @@ static int power_saving_thread(void *data)
while (!kthread_should_stop()) {
int cpu;
- u64 expire_time;
+ unsigned long expire_time;
try_to_freeze();
/* round robin to cpus */
- if (last_jiffies + round_robin_time * HZ < jiffies) {
+ expire_time = last_jiffies + round_robin_time * HZ;
+ if (time_before(expire_time, jiffies)) {
last_jiffies = jiffies;
round_robin_cpu(tsk_index);
}
@@ -200,7 +201,7 @@ static int power_saving_thread(void *data)
CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
local_irq_enable();
- if (jiffies > expire_time) {
+ if (time_before(expire_time, jiffies)) {
do_sleep = 1;
break;
}
@@ -215,8 +216,15 @@ static int power_saving_thread(void *data)
* borrow CPU time from this CPU and cause RT task use > 95%
* CPU time. To make 'avoid starvation' work, takes a nap here.
*/
- if (do_sleep)
+ if (unlikely(do_sleep))
schedule_timeout_killable(HZ * idle_pct / 100);
+
+ /* If an external event has set the need_resched flag, then
+ * we need to deal with it, or this loop will continue to
+ * spin without calling __mwait().
+ */
+ if (unlikely(need_resched()))
+ schedule();
}
exit_round_robin(tsk_index);
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 1d4950388fa..2bf9082f752 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -22,27 +22,16 @@
ACPI_MODULE_NAME("platform");
-/*
- * The following ACPI IDs are known to be suitable for representing as
- * platform devices.
- */
-static const struct acpi_device_id acpi_platform_device_ids[] = {
-
- { "PNP0D40" },
- { "VPC2004" },
- { "BCM4752" },
-
- /* Intel Smart Sound Technology */
- { "INT33C8" },
- { "80860F28" },
-
- { }
+static const struct acpi_device_id forbidden_id_list[] = {
+ {"PNP0000", 0}, /* PIC */
+ {"PNP0100", 0}, /* Timer */
+ {