aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/power/swsusp.txt13
-rw-r--r--drivers/acpi/acpi_lpss.c7
-rw-r--r--drivers/acpi/osl.c12
-rw-r--r--drivers/acpi/resource.c162
-rw-r--r--drivers/acpi/scan.c32
-rw-r--r--drivers/ata/Kconfig2
-rw-r--r--drivers/ata/ahci_platform.c9
-rw-r--r--drivers/base/power/domain.c13
-rw-r--r--drivers/base/power/wakeirq.c12
-rw-r--r--drivers/base/power/wakeup.c31
-rw-r--r--drivers/pnp/system.c35
-rw-r--r--include/linux/acpi.h24
-rw-r--r--include/linux/mod_devicetable.h2
-rw-r--r--scripts/mod/devicetable-offsets.c2
-rw-r--r--scripts/mod/file2alias.c32
15 files changed, 148 insertions, 240 deletions
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
index f732a8321e8a..8cc17ca71813 100644
--- a/Documentation/power/swsusp.txt
+++ b/Documentation/power/swsusp.txt
@@ -410,8 +410,17 @@ Documentation/usb/persist.txt.
410 410
411Q: Can I suspend-to-disk using a swap partition under LVM? 411Q: Can I suspend-to-disk using a swap partition under LVM?
412 412
413A: No. You can suspend successfully, but you'll not be able to 413A: Yes and No. You can suspend successfully, but the kernel will not be able
414resume. uswsusp should be able to work with LVM. See suspend.sf.net. 414to resume on its own. You need an initramfs that can recognize the resume
415situation, activate the logical volume containing the swap volume (but not
416touch any filesystems!), and eventually call
417
418echo -n "$major:$minor" > /sys/power/resume
419
420where $major and $minor are the respective major and minor device numbers of
421the swap volume.
422
423uswsusp works with LVM, too. See http://suspend.sourceforge.net/
415 424
416Q: I upgraded the kernel from 2.6.15 to 2.6.16. Both kernels were 425Q: I upgraded the kernel from 2.6.15 to 2.6.16. Both kernels were
417compiled with the similar configuration files. Anyway I found that 426compiled with the similar configuration files. Anyway I found that
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 569ee090343f..46b58abb08c5 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -352,13 +352,16 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
352 pdata->mmio_size = resource_size(rentry->res); 352 pdata->mmio_size = resource_size(rentry->res);
353 pdata->mmio_base = ioremap(rentry->res->start, 353 pdata->mmio_base = ioremap(rentry->res->start,
354 pdata->mmio_size); 354 pdata->mmio_size);
355 if (!pdata->mmio_base)
356 goto err_out;
357 break; 355 break;
358 } 356 }
359 357
360 acpi_dev_free_resource_list(&resource_list); 358 acpi_dev_free_resource_list(&resource_list);
361 359
360 if (!pdata->mmio_base) {
361 ret = -ENOMEM;
362 goto err_out;
363 }
364
362 pdata->dev_desc = dev_desc; 365 pdata->dev_desc = dev_desc;
363 366
364 if (dev_desc->setup) 367 if (dev_desc->setup)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index c262e4acd68d..3b8963f21b36 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -175,10 +175,14 @@ static void __init acpi_request_region (struct acpi_generic_address *gas,
175 if (!addr || !length) 175 if (!addr || !length)
176 return; 176 return;
177 177
178 acpi_reserve_region(addr, length, gas->space_id, 0, desc); 178 /* Resources are never freed */
179 if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
180 request_region(addr, length, desc);
181 else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
182 request_mem_region(addr, length, desc);
179} 183}
180 184
181static void __init acpi_reserve_resources(void) 185static int __init acpi_reserve_resources(void)
182{ 186{
183 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length, 187 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
184 "ACPI PM1a_EVT_BLK"); 188 "ACPI PM1a_EVT_BLK");
@@ -207,7 +211,10 @@ static void __init acpi_reserve_resources(void)
207 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) 211 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
208 acpi_request_region(&acpi_gbl_FADT.xgpe1_block, 212 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
209 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); 213 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
214
215 return 0;
210} 216}
217fs_initcall_sync(acpi_reserve_resources);
211 218
212void acpi_os_printf(const char *fmt, ...) 219void acpi_os_printf(const char *fmt, ...)
213{ 220{
@@ -1862,7 +1869,6 @@ acpi_status __init acpi_os_initialize(void)
1862 1869
1863acpi_status __init acpi_os_initialize1(void) 1870acpi_status __init acpi_os_initialize1(void)
1864{ 1871{
1865 acpi_reserve_resources();
1866 kacpid_wq = alloc_workqueue("kacpid", 0, 1); 1872 kacpid_wq = alloc_workqueue("kacpid", 0, 1);
1867 kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); 1873 kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
1868 kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0); 1874 kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 10561ce16ed1..8244f013f210 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -26,7 +26,6 @@
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/export.h> 27#include <linux/export.h>
28#include <linux/ioport.h> 28#include <linux/ioport.h>
29#include <linux/list.h>
30#include <linux/slab.h> 29#include <linux/slab.h>
31 30
32#ifdef CONFIG_X86 31#ifdef CONFIG_X86
@@ -622,164 +621,3 @@ int acpi_dev_filter_resource_type(struct acpi_resource *ares,
622 return (type & types) ? 0 : 1; 621 return (type & types) ? 0 : 1;
623} 622}
624EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type); 623EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
625
626struct reserved_region {
627 struct list_head node;
628 u64 start;
629 u64 end;
630};
631
632static LIST_HEAD(reserved_io_regions);
633static LIST_HEAD(reserved_mem_regions);
634
635static int request_range(u64 start, u64 end, u8 space_id, unsigned long flags,
636 char *desc)
637{
638 unsigned int length = end - start + 1;
639 struct resource *res;
640
641 res = space_id == ACPI_ADR_SPACE_SYSTEM_IO ?
642 request_region(start, length, desc) :
643 request_mem_region(start, length, desc);
644 if (!res)
645 return -EIO;
646
647 res->flags &= ~flags;
648 return 0;
649}
650
651static int add_region_before(u64 start, u64 end, u8 space_id,
652 unsigned long flags, char *desc,
653 struct list_head *head)
654{
655 struct reserved_region *reg;
656 int error;
657
658 reg = kmalloc(sizeof(*reg), GFP_KERNEL);
659 if (!reg)
660 return -ENOMEM;
661
662 error = request_range(start, end, space_id, flags, desc);
663 if (error) {
664 kfree(reg);
665 return error;
666 }
667
668 reg->start = start;
669 reg->end = end;
670 list_add_tail(&reg->node, head);
671 return 0;
672}
673
674/**
675 * acpi_reserve_region - Reserve an I/O or memory region as a system resource.
676 * @start: Starting address of the region.
677 * @length: Length of the region.
678 * @space_id: Identifier of address space to reserve the region from.
679 * @flags: Resource flags to clear for the region after requesting it.
680 * @desc: Region description (for messages).
681 *
682 * Reserve an I/O or memory region as a system resource to prevent others from
683 * using it. If the new region overlaps with one of the regions (in the given
684 * address space) already reserved by this routine, only the non-overlapping
685 * parts of it will be reserved.
686 *
687 * Returned is either 0 (success) or a negative error code indicating a resource
688 * reservation problem. It is the code of the first encountered error, but the
689 * routine doesn't abort until it has attempted to request all of the parts of
690 * the new region that don't overlap with other regions reserved previously.
691 *
692 * The resources requested by this routine are never released.
693 */
694int acpi_reserve_region(u64 start, unsigned int length, u8 space_id,
695 unsigned long flags, char *desc)
696{
697 struct list_head *regions;
698 struct reserved_region *reg;
699 u64 end = start + length - 1;
700 int ret = 0, error = 0;
701
702 if (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
703 regions = &reserved_io_regions;
704 else if (space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
705 regions = &reserved_mem_regions;
706 else
707 return -EINVAL;
708
709 if (list_empty(regions))
710 return add_region_before(start, end, space_id, flags, desc, regions);
711
712 list_for_each_entry(reg, regions, node)
713 if (reg->start == end + 1) {
714 /* The new region can be prepended to this one. */
715 ret = request_range(start, end, space_id, flags, desc);
716 if (!ret)
717 reg->start = start;
718
719 return ret;
720 } else if (reg->start > end) {
721 /* No overlap. Add the new region here and get out. */
722 return add_region_before(start, end, space_id, flags,
723 desc, &reg->node);
724 } else if (reg->end == start - 1) {
725 goto combine;
726 } else if (reg->end >= start) {
727 goto overlap;
728 }
729
730 /* The new region goes after the last existing one. */
731 return add_region_before(start, end, space_id, flags, desc, regions);
732
733 overlap:
734 /*
735 * The new region overlaps an existing one.
736 *
737 * The head part of the new region immediately preceding the existing
738 * overlapping one can be combined with it right away.
739 */
740 if (reg->start > start) {
741 error = request_range(start, reg->start - 1, space_id, flags, desc);
742 if (error)
743 ret = error;
744 else
745 reg->start = start;
746 }
747
748 combine:
749 /*
750 * The new region is adjacent to an existing one. If it extends beyond
751 * that region all the way to the next one, it is possible to combine
752 * all three of them.
753 */
754 while (reg->end < end) {
755 struct reserved_region *next = NULL;
756 u64 a = reg->end + 1, b = end;
757
758 if (!list_is_last(&reg->node, regions)) {
759 next = list_next_entry(reg, node);
760 if (next->start <= end)
761 b = next->start - 1;
762 }
763 error = request_range(a, b, space_id, flags, desc);
764 if (!error) {
765 if (next && next->start == b + 1) {
766 reg->end = next->end;
767 list_del(&next->node);
768 kfree(next);
769 } else {
770 reg->end = end;
771 break;
772 }
773 } else if (next) {
774 if (!ret)
775 ret = error;
776
777 reg = next;
778 } else {
779 break;
780 }
781 }
782
783 return ret ? ret : error;
784}
785EXPORT_SYMBOL_GPL(acpi_reserve_region);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 2649a068671d..ec256352f423 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1019,6 +1019,29 @@ static bool acpi_of_match_device(struct acpi_device *adev,
1019 return false; 1019 return false;
1020} 1020}
1021 1021
1022static bool __acpi_match_device_cls(const struct acpi_device_id *id,
1023 struct acpi_hardware_id *hwid)
1024{
1025 int i, msk, byte_shift;
1026 char buf[3];
1027
1028 if (!id->cls)
1029 return false;
1030
1031 /* Apply class-code bitmask, before checking each class-code byte */
1032 for (i = 1; i <= 3; i++) {
1033 byte_shift = 8 * (3 - i);
1034 msk = (id->cls_msk >> byte_shift) & 0xFF;
1035 if (!msk)
1036 continue;
1037
1038 sprintf(buf, "%02x", (id->cls >> byte_shift) & msk);
1039 if (strncmp(buf, &hwid->id[(i - 1) * 2], 2))
1040 return false;
1041 }
1042 return true;
1043}
1044
1022static const struct acpi_device_id *__acpi_match_device( 1045static const struct acpi_device_id *__acpi_match_device(
1023 struct acpi_device *device, 1046 struct acpi_device *device,
1024 const struct acpi_device_id *ids, 1047 const struct acpi_device_id *ids,
@@ -1036,9 +1059,12 @@ static const struct acpi_device_id *__acpi_match_device(
1036 1059
1037 list_for_each_entry(hwid, &device->pnp.ids, list) { 1060 list_for_each_entry(hwid, &device->pnp.ids, list) {
1038 /* First, check the ACPI/PNP IDs provided by the caller. */ 1061 /* First, check the ACPI/PNP IDs provided by the caller. */
1039 for (id = ids; id->id[0]; id++) 1062 for (id = ids; id->id[0] || id->cls; id++) {
1040 if (!strcmp((char *) id->id, hwid->id)) 1063 if (id->id[0] && !strcmp((char *) id->id, hwid->id))
1041 return id; 1064 return id;
1065 else if (id->cls && __acpi_match_device_cls(id, hwid))
1066 return id;
1067 }
1042 1068
1043 /* 1069 /*
1044 * Next, check ACPI_DT_NAMESPACE_HID and try to match the 1070 * Next, check ACPI_DT_NAMESPACE_HID and try to match the
@@ -2101,6 +2127,8 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
2101 if (info->valid & ACPI_VALID_UID) 2127 if (info->valid & ACPI_VALID_UID)
2102 pnp->unique_id = kstrdup(info->unique_id.string, 2128 pnp->unique_id = kstrdup(info->unique_id.string,
2103 GFP_KERNEL); 2129 GFP_KERNEL);
2130 if (info->valid & ACPI_VALID_CLS)
2131 acpi_add_id(pnp, info->class_code.string);
2104 2132
2105 kfree(info); 2133 kfree(info);
2106 2134
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 6d17a3b65ef7..15e40ee62a94 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -48,7 +48,7 @@ config ATA_VERBOSE_ERROR
48 48
49config ATA_ACPI 49config ATA_ACPI
50 bool "ATA ACPI Support" 50 bool "ATA ACPI Support"
51 depends on ACPI && PCI 51 depends on ACPI
52 default y 52 default y
53 help 53 help
54 This option adds support for ATA-related ACPI objects. 54 This option adds support for ATA-related ACPI objects.
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 614c78f510f0..1befb114c384 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -20,6 +20,8 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/libata.h> 21#include <linux/libata.h>
22#include <linux/ahci_platform.h> 22#include <linux/ahci_platform.h>
23#include <linux/acpi.h>
24#include <linux/pci_ids.h>
23#include "ahci.h" 25#include "ahci.h"
24 26
25#define DRV_NAME "ahci" 27#define DRV_NAME "ahci"
@@ -79,12 +81,19 @@ static const struct of_device_id ahci_of_match[] = {
79}; 81};
80MODULE_DEVICE_TABLE(of, ahci_of_match); 82MODULE_DEVICE_TABLE(of, ahci_of_match);
81 83
84static const struct acpi_device_id ahci_acpi_match[] = {
85 { ACPI_DEVICE_CLASS(PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff) },
86 {},
87};
88MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
89
82static struct platform_driver ahci_driver = { 90static struct platform_driver ahci_driver = {
83 .probe = ahci_probe, 91 .probe = ahci_probe,
84 .remove = ata_platform_remove_one, 92 .remove = ata_platform_remove_one,
85 .driver = { 93 .driver = {
86 .name = DRV_NAME, 94 .name = DRV_NAME,
87 .of_match_table = ahci_of_match, 95 .of_match_table = ahci_of_match,
96 .acpi_match_table = ahci_acpi_match,
88 .pm = &ahci_pm_ops, 97 .pm = &ahci_pm_ops,
89 }, 98 },
90}; 99};
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index cdd547bd67df..0ee43c1056e0 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -6,6 +6,7 @@
6 * This file is released under the GPLv2. 6 * This file is released under the GPLv2.
7 */ 7 */
8 8
9#include <linux/delay.h>
9#include <linux/kernel.h> 10#include <linux/kernel.h>
10#include <linux/io.h> 11#include <linux/io.h>
11#include <linux/platform_device.h> 12#include <linux/platform_device.h>
@@ -19,6 +20,8 @@
19#include <linux/suspend.h> 20#include <linux/suspend.h>
20#include <linux/export.h> 21#include <linux/export.h>
21 22
23#define GENPD_RETRY_MAX_MS 250 /* Approximate */
24
22#define GENPD_DEV_CALLBACK(genpd, type, callback, dev) \ 25#define GENPD_DEV_CALLBACK(genpd, type, callback, dev) \
23({ \ 26({ \
24 type (*__routine)(struct device *__d); \ 27 type (*__routine)(struct device *__d); \
@@ -2131,6 +2134,7 @@ EXPORT_SYMBOL_GPL(of_genpd_get_from_provider);
2131static void genpd_dev_pm_detach(struct device *dev, bool power_off) 2134static void genpd_dev_pm_detach(struct device *dev, bool power_off)
2132{ 2135{
2133 struct generic_pm_domain *pd; 2136 struct generic_pm_domain *pd;
2137 unsigned int i;
2134 int ret = 0; 2138 int ret = 0;
2135 2139
2136 pd = pm_genpd_lookup_dev(dev); 2140 pd = pm_genpd_lookup_dev(dev);
@@ -2139,10 +2143,12 @@ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
2139 2143
2140 dev_dbg(dev, "removing from PM domain %s\n", pd->name); 2144 dev_dbg(dev, "removing from PM domain %s\n", pd->name);
2141 2145
2142 while (1) { 2146 for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) {
2143 ret = pm_genpd_remove_device(pd, dev); 2147 ret = pm_genpd_remove_device(pd, dev);
2144 if (ret != -EAGAIN) 2148 if (ret != -EAGAIN)
2145 break; 2149 break;
2150
2151 mdelay(i);
2146 cond_resched(); 2152 cond_resched();
2147 } 2153 }
2148 2154
@@ -2183,6 +2189,7 @@ int genpd_dev_pm_attach(struct device *dev)
2183{ 2189{
2184 struct of_phandle_args pd_args; 2190 struct of_phandle_args pd_args;
2185 struct generic_pm_domain *pd; 2191 struct generic_pm_domain *pd;
2192 unsigned int i;
2186 int ret; 2193 int ret;
2187 2194
2188 if (!dev->of_node) 2195 if (!dev->of_node)
@@ -2218,10 +2225,12 @@ int genpd_dev_pm_attach(struct device *dev)
2218 2225
2219 dev_dbg(dev, "adding to PM domain %s\n", pd->name); 2226 dev_dbg(dev, "adding to PM domain %s\n", pd->name);
2220 2227
2221 while (1) { 2228 for (i = 1; i < GENPD_RETRY_MAX_MS; i <<= 1) {
2222 ret = pm_genpd_add_device(pd, dev); 2229 ret = pm_genpd_add_device(pd, dev);
2223 if (ret != -EAGAIN) 2230 if (ret != -EAGAIN)
2224 break; 2231 break;
2232
2233 mdelay(i);
2225 cond_resched(); 2234 cond_resched();
2226 } 2235 }
2227 2236
diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c
index 7470004ca810..eb6e67451dec 100644
--- a/drivers/base/power/wakeirq.c
+++ b/drivers/base/power/wakeirq.c
@@ -45,14 +45,12 @@ static int dev_pm_attach_wake_irq(struct device *dev, int irq,
45 return -EEXIST; 45 return -EEXIST;
46 } 46 }
47 47
48 dev->power.wakeirq = wirq;
49 spin_unlock_irqrestore(&dev->power.lock, flags);
50
51 err = device_wakeup_attach_irq(dev, wirq); 48 err = device_wakeup_attach_irq(dev, wirq);
52 if (err) 49 if (!err)
53 return err; 50 dev->power.wakeirq = wirq;
54 51
55 return 0; 52 spin_unlock_irqrestore(&dev->power.lock, flags);
53 return err;
56} 54}
57 55
58/** 56/**
@@ -105,10 +103,10 @@ void dev_pm_clear_wake_irq(struct device *dev)
105 return; 103 return;
106 104
107 spin_lock_irqsave(&dev->power.lock, flags); 105 spin_lock_irqsave(&dev->power.lock, flags);
106 device_wakeup_detach_irq(dev);
108 dev->power.wakeirq = NULL; 107 dev->power.wakeirq = NULL;
109 spin_unlock_irqrestore(&dev->power.lock, flags); 108 spin_unlock_irqrestore(&dev->power.lock, flags);
110 109
111 device_wakeup_detach_irq(dev);
112 if (wirq->dedicated_irq) 110 if (wirq->dedicated_irq)
113 free_irq(wirq->irq, wirq); 111 free_irq(wirq->irq, wirq);
114 kfree(wirq); 112 kfree(wirq);
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 40f71603378c..51f15bc15774 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -281,32 +281,25 @@ EXPORT_SYMBOL_GPL(device_wakeup_enable);
281 * Attach a device wakeirq to the wakeup source so the device 281 * Attach a device wakeirq to the wakeup source so the device
282 * wake IRQ can be configured automatically for suspend and 282 * wake IRQ can be configured automatically for suspend and
283 * resume. 283 * resume.
284 *
285 * Call under the device's power.lock lock.
284 */ 286 */
285int device_wakeup_attach_irq(struct device *dev, 287int device_wakeup_attach_irq(struct device *dev,
286 struct wake_irq *wakeirq) 288 struct wake_irq *wakeirq)
287{ 289{
288 struct wakeup_source *ws; 290 struct wakeup_source *ws;
289 int ret = 0;
290 291
291 spin_lock_irq(&dev->power.lock);
292 ws = dev->power.wakeup; 292 ws = dev->power.wakeup;
293 if (!ws) { 293 if (!ws) {
294 dev_err(dev, "forgot to call call device_init_wakeup?\n"); 294 dev_err(dev, "forgot to call call device_init_wakeup?\n");
295 ret = -EINVAL; 295 return -EINVAL;
296 goto unlock;
297 } 296 }
298 297
299 if (ws->wakeirq) { 298 if (ws->wakeirq)
300 ret = -EEXIST; 299 return -EEXIST;
301 goto unlock;
302 }
303 300
304 ws->wakeirq = wakeirq; 301 ws->wakeirq = wakeirq;
305 302 return 0;
306unlock:
307 spin_unlock_irq(&dev->power.lock);
308
309 return ret;
310} 303}
311 304
312/** 305/**
@@ -314,20 +307,16 @@ unlock:
314 * @dev: Device to handle 307 * @dev: Device to handle
315 * 308 *
316 * Removes a device wakeirq from the wakeup source. 309 * Removes a device wakeirq from the wakeup source.
310 *
311 * Call under the device's power.lock lock.
317 */ 312 */
318void device_wakeup_detach_irq(struct device *dev) 313void device_wakeup_detach_irq(struct device *dev)
319{ 314{
320 struct wakeup_source *ws; 315 struct wakeup_source *ws;
321 316
322 spin_lock_irq(&dev->power.lock);
323 ws = dev->power.wakeup; 317 ws = dev->power.wakeup;
324 if (!ws) 318 if (ws)
325 goto unlock; 319 ws->wakeirq = NULL;
326
327 ws->wakeirq = NULL;
328
329unlock:
330 spin_unlock_irq(&dev->power.lock);
331} 320}
332 321
333/** 322/**
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index 515f33882ab8..49c1720df59a 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -7,7 +7,6 @@
7 * Bjorn Helgaas <bjorn.helgaas@hp.com> 7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
8 */ 8 */
9 9
10#include <linux/acpi.h>
11#include <linux/pnp.h> 10#include <linux/pnp.h>
12#include <linux/device.h> 11#include <linux/device.h>
13#include <linux/init.h> 12#include <linux/init.h>
@@ -23,41 +22,25 @@ static const struct pnp_device_id pnp_dev_table[] = {
23 {"", 0} 22 {"", 0}
24}; 23};
25 24
26#ifdef CONFIG_ACPI
27static bool __reserve_range(u64 start, unsigned int length, bool io, char *desc)
28{
29 u8 space_id = io ? ACPI_ADR_SPACE_SYSTEM_IO : ACPI_ADR_SPACE_SYSTEM_MEMORY;
30 return !acpi_reserve_region(start, length, space_id, IORESOURCE_BUSY, desc);
31}
32#else
33static bool __reserve_range(u64 start, unsigned int length, bool io, char *desc)
34{
35 struct resource *res;
36
37 res = io ? request_region(start, length, desc) :
38 request_mem_region(start, length, desc);
39 if (res) {
40 res->flags &= ~IORESOURCE_BUSY;
41 return true;
42 }
43 return false;
44}
45#endif
46
47static void reserve_range(struct pnp_dev *dev, struct resource *r, int port) 25static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
48{ 26{
49 char *regionid; 27 char *regionid;
50 const char *pnpid = dev_name(&dev->dev); 28 const char *pnpid = dev_name(&dev->dev);
51 resource_size_t start = r->start, end = r->end; 29 resource_size_t start = r->start, end = r->end;
52 bool reserved; 30 struct resource *res;
53 31
54 regionid = kmalloc(16, GFP_KERNEL); 32 regionid = kmalloc(16, GFP_KERNEL);
55 if (!regionid) 33 if (!regionid)
56 return; 34 return;
57 35
58 snprintf(regionid, 16, "pnp %s", pnpid); 36 snprintf(regionid, 16, "pnp %s", pnpid);
59 reserved = __reserve_range(start, end - start + 1, !!port, regionid); 37 if (port)
60 if (!reserved) 38 res = request_region(start, end - start + 1, regionid);
39 else
40 res = request_mem_region(start, end - start + 1, regionid);
41 if (res)
42 res->flags &= ~IORESOURCE_BUSY;
43 else
61 kfree(regionid); 44 kfree(regionid);
62 45
63 /* 46 /*
@@ -66,7 +49,7 @@ static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
66 * have double reservations. 49 * have double reservations.
67 */ 50 */
68 dev_info(&dev->dev, "%pR %s reserved\n", r, 51 dev_info(&dev->dev, "%pR %s reserved\n", r,
69 reserved ? "has been" : "could not be"); 52 res ? "has been" : "could not be");
70} 53}
71 54
72static void reserve_resources_of_dev(struct pnp_dev *dev) 55static void reserve_resources_of_dev(struct pnp_dev *dev)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index c471dfc93b71..d2445fa9999f 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -58,6 +58,19 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
58 acpi_fwnode_handle(adev) : NULL) 58 acpi_fwnode_handle(adev) : NULL)
59#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) 59#define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev))
60 60
61/**
62 * ACPI_DEVICE_CLASS - macro used to describe an ACPI device with
63 * the PCI-defined class-code information
64 *
65 * @_cls : the class, subclass, prog-if triple for this device
66 * @_msk : the class mask for this device
67 *
68 * This macro is used to create a struct acpi_device_id that matches a
69 * specific PCI class. The .id and .driver_data fields will be left
70 * initialized with the default value.
71 */
72#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk),
73
61static inline bool has_acpi_companion(struct device *dev) 74static inline bool has_acpi_companion(struct device *dev)
62{ 75{
63 return is_acpi_node(dev->fwnode); 76 return is_acpi_node(dev->fwnode);
@@ -309,9 +322,6 @@ int acpi_check_region(resource_size_t start, resource_size_t n,
309 322
310int acpi_resources_are_enforced(void); 323int acpi_resources_are_enforced(void);
311 324
312int acpi_reserve_region(u64 start, unsigned int length, u8 space_id,
313 unsigned long flags, char *desc);
314
315#ifdef CONFIG_HIBERNATION 325#ifdef CONFIG_HIBERNATION
316void __init acpi_no_s4_hw_signature(void); 326void __init acpi_no_s4_hw_signature(void);
317#endif 327#endif
@@ -446,6 +456,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *);
446#define ACPI_COMPANION(dev) (NULL) 456#define ACPI_COMPANION(dev) (NULL)
447#define ACPI_COMPANION_SET(dev, adev) do { } while (0) 457#define ACPI_COMPANION_SET(dev, adev) do { } while (0)
448#define ACPI_HANDLE(dev) (NULL) 458#define ACPI_HANDLE(dev) (NULL)
459#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (0), .cls_msk = (0),
449 460
450struct fwnode_handle; 461struct fwnode_handle;
451 462
@@ -507,13 +518,6 @@ static inline int acpi_check_region(resource_size_t start, resource_size_t n,
507 return 0; 518 return 0;
508} 519}
509 520
510static inline int acpi_reserve_region(u64 start, unsigned int length,
511 u8 space_id, unsigned long flags,
512 char *desc)
513{
514 return -ENXIO;
515}
516
517struct acpi_table_header; 521struct acpi_table_header;
518static inline int acpi_table_parse(char *id, 522static inline int acpi_table_parse(char *id,
519 int (*handler)(struct acpi_table_header *)) 523 int (*handler)(struct acpi_table_header *))
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 8183d6640ca7..34f25b7bf642 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -189,6 +189,8 @@ struct css_device_id {
189struct acpi_device_id { 189struct acpi_device_id {
190 __u8 id[ACPI_ID_LEN]; 190 __u8 id[ACPI_ID_LEN];
191 kernel_ulong_t driver_data; 191 kernel_ulong_t driver_data;
192 __u32 cls;
193 __u32 cls_msk;
192}; 194};
193 195
194#define PNP_ID_LEN 8 196#define PNP_ID_LEN 8
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index eff7de1fc82e..e70fcd12eeeb 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -63,6 +63,8 @@ int main(void)
63 63
64 DEVID(acpi_device_id); 64 DEVID(acpi_device_id);
65 DEVID_FIELD(acpi_device_id, id); 65 DEVID_FIELD(acpi_device_id, id);
66 DEVID_FIELD(acpi_device_id, cls);
67 DEVID_FIELD(acpi_device_id, cls_msk);
66 68
67 DEVID(pnp_device_id); 69 DEVID(pnp_device_id);
68 DEVID_FIELD(pnp_device_id, id); 70 DEVID_FIELD(pnp_device_id, id);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 84c86f3cd6cd..5f2088209132 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -523,12 +523,40 @@ static int do_serio_entry(const char *filename,
523} 523}
524ADD_TO_DEVTABLE("serio", serio_device_id, do_serio_entry); 524ADD_TO_DEVTABLE("serio", serio_device_id, do_serio_entry);
525 525
526/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */ 526/* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or
527 * "acpi:bbsspp" (bb=base-class, ss=sub-class, pp=prog-if)
528 *
529 * NOTE: Each driver should use one of the following : _HID, _CIDs
530 * or _CLS. Also, bb, ss, and pp can be substituted with ??
531 * as don't care byte.
532 */
527static int do_acpi_entry(const char *filename, 533static int do_acpi_entry(const char *filename,
528 void *symval, char *alias) 534 void *symval, char *alias)
529{ 535{
530 DEF_FIELD_ADDR(symval, acpi_device_id, id); 536 DEF_FIELD_ADDR(symval, acpi_device_id, id);
531 sprintf(alias, "acpi*:%s:*", *id); 537 DEF_FIELD_ADDR(symval, acpi_device_id, cls);
538 DEF_FIELD_ADDR(symval, acpi_device_id, cls_msk);
539
540 if (id && strlen((const char *)*id))
541 sprintf(alias, "acpi*:%s:*", *id);
542 else if (cls) {
543 int i, byte_shift, cnt = 0;
544 unsigned int msk;
545
546 sprintf(&alias[cnt], "acpi*:");
547 cnt = 6;
548 for (i = 1; i <= 3; i++) {
549 byte_shift = 8 * (3-i);
550 msk = (*cls_msk >> byte_shift) & 0xFF;
551 if (msk)
552 sprintf(&alias[cnt], "%02x",
553 (*cls >> byte_shift) & 0xFF);
554 else
555 sprintf(&alias[cnt], "??");
556 cnt += 2;
557 }
558 sprintf(&alias[cnt], ":*");
559 }
532 return 1; 560 return 1;
533} 561}
534ADD_TO_DEVTABLE("acpi", acpi_device_id, do_acpi_entry); 562ADD_TO_DEVTABLE("acpi", acpi_device_id, do_acpi_entry);