From 4c98cfef2efa6b6662ac28c4f0069964bbd9fdf9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 29 Nov 2005 09:09:32 +0100 Subject: [ALSA] PATCH] Add PM support to PnP drivers Add suspend/resume callback to pnp_driver and pnp_card_driver. Signed-off-by: Takashi Iwai --- drivers/pnp/card.c | 25 +++++++++++++++++++++++++ drivers/pnp/driver.c | 20 ++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'drivers/pnp') diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index bd7c966ea2d7..0ecbe4edbec1 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -69,6 +69,7 @@ static int card_probe(struct pnp_card * card, struct pnp_card_driver * drv) return 0; clink->card = card; clink->driver = drv; + clink->pm_state = PMSG_ON; if (drv->probe) { if (drv->probe(clink, id)>=0) return 1; @@ -333,6 +334,28 @@ void pnp_release_card_device(struct pnp_dev * dev) up_write(&dev->dev.bus->subsys.rwsem); } +/* + * suspend/resume callbacks + */ +static int card_suspend(struct pnp_dev *dev, pm_message_t state) +{ + struct pnp_card_link *link = dev->card_link; + if (link->pm_state.event == state.event) + return 0; + link->pm_state = state; + return link->driver->suspend(link, state); +} + +static int card_resume(struct pnp_dev *dev) +{ + struct pnp_card_link *link = dev->card_link; + if (link->pm_state.event == PM_EVENT_ON) + return 0; + link->pm_state = PMSG_ON; + link->driver->resume(link); + return 0; +} + /** * pnp_register_card_driver - registers a PnP card driver with the PnP Layer * @drv: pointer to the driver to register @@ -348,6 +371,8 @@ int pnp_register_card_driver(struct pnp_card_driver * drv) drv->link.flags = drv->flags; drv->link.probe = NULL; drv->link.remove = &card_remove_first; + drv->link.suspend = drv->suspend ? card_suspend : NULL; + drv->link.resume = drv->resume ? card_resume : NULL; spin_lock(&pnp_lock); list_add_tail(&drv->global_list, &pnp_card_drivers); diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index d3ccce706ab4..ea2cb9a8b21d 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -146,10 +146,30 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv) return 1; } +static int pnp_bus_suspend(struct device *dev, pm_message_t state) +{ + struct pnp_dev * pnp_dev = to_pnp_dev(dev); + struct pnp_driver * pnp_drv = pnp_dev->driver; + + if (pnp_drv && pnp_drv->suspend) + return pnp_drv->suspend(pnp_dev, state); + return 0; +} + +static void pnp_bus_resume(struct device *dev) +{ + struct pnp_dev * pnp_dev = to_pnp_dev(dev); + struct pnp_driver * pnp_drv = pnp_dev->driver; + + if (pnp_drv && pnp_drv->resume) + pnp_drv->resume(pnp_dev); +} struct bus_type pnp_bus_type = { .name = "pnp", .match = pnp_bus_match, + .suspend = pnp_bus_suspend, + .resume = pnp_bus_resume, }; -- cgit v1.2.3 From 68094e3251a664ee1389fcf179497237cbf78331 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 29 Nov 2005 09:09:32 +0100 Subject: [ALSA] [PATCH] alsa: Improved PnP suspend support Also use the PnP functions to start/stop the devices during the suspend so that drivers will not have to duplicate this code. Cc: Adam Belay Cc: Jaroslav Kysela Cc: Takashi Iwai Signed-off-by: Pierre Ossman Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- drivers/pnp/driver.c | 37 ++++++++++++++++++++---- drivers/pnp/manager.c | 78 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 91 insertions(+), 24 deletions(-) (limited to 'drivers/pnp') diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index ea2cb9a8b21d..15fb758a9e52 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -150,19 +150,46 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state) { struct pnp_dev * pnp_dev = to_pnp_dev(dev); struct pnp_driver * pnp_drv = pnp_dev->driver; + int error; + + if (!pnp_drv) + return 0; + + if (pnp_drv->suspend) { + error = pnp_drv->suspend(pnp_dev, state); + if (error) + return error; + } + + if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) && + pnp_can_disable(pnp_dev)) { + error = pnp_stop_dev(pnp_dev); + if (error) + return error; + } - if (pnp_drv && pnp_drv->suspend) - return pnp_drv->suspend(pnp_dev, state); return 0; } -static void pnp_bus_resume(struct device *dev) +static int pnp_bus_resume(struct device *dev) { struct pnp_dev * pnp_dev = to_pnp_dev(dev); struct pnp_driver * pnp_drv = pnp_dev->driver; + int error; + + if (!pnp_drv) + return 0; + + if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) { + error = pnp_start_dev(pnp_dev); + if (error) + return error; + } - if (pnp_drv && pnp_drv->resume) - pnp_drv->resume(pnp_dev); + if (pnp_drv->resume) + return pnp_drv->resume(pnp_dev); + + return 0; } struct bus_type pnp_bus_type = { diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 261668618b2d..c4256aa32bcb 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -469,6 +469,53 @@ int pnp_auto_config_dev(struct pnp_dev *dev) return -EBUSY; } +/** + * pnp_start_dev - low-level start of the PnP device + * @dev: pointer to the desired device + * + * assumes that resources have alread been allocated + */ + +int pnp_start_dev(struct pnp_dev *dev) +{ + if (!pnp_can_write(dev)) { + pnp_info("Device %s does not supported activation.", dev->dev.bus_id); + return -EINVAL; + } + + if (dev->protocol->set(dev, &dev->res)<0) { + pnp_err("Failed to activate device %s.", dev->dev.bus_id); + return -EIO; + } + + pnp_info("Device %s activated.", dev->dev.bus_id); + + return 0; +} + +/** + * pnp_stop_dev - low-level disable of the PnP device + * @dev: pointer to the desired device + * + * does not free resources + */ + +int pnp_stop_dev(struct pnp_dev *dev) +{ + if (!pnp_can_disable(dev)) { + pnp_info("Device %s does not supported disabling.", dev->dev.bus_id); + return -EINVAL; + } + if (dev->protocol->disable(dev)<0) { + pnp_err("Failed to disable device %s.", dev->dev.bus_id); + return -EIO; + } + + pnp_info("Device %s disabled.", dev->dev.bus_id); + + return 0; +} + /** * pnp_activate_dev - activates a PnP device for use * @dev: pointer to the desired device @@ -477,6 +524,8 @@ int pnp_auto_config_dev(struct pnp_dev *dev) */ int pnp_activate_dev(struct pnp_dev *dev) { + int error; + if (!dev) return -EINVAL; if (dev->active) { @@ -487,18 +536,11 @@ int pnp_activate_dev(struct pnp_dev *dev) if (pnp_auto_config_dev(dev)) return -EBUSY; - if (!pnp_can_write(dev)) { - pnp_info("Device %s does not supported activation.", dev->dev.bus_id); - return -EINVAL; - } - - if (dev->protocol->set(dev, &dev->res)<0) { - pnp_err("Failed to activate device %s.", dev->dev.bus_id); - return -EIO; - } + error = pnp_start_dev(dev); + if (error) + return error; dev->active = 1; - pnp_info("Device %s activated.", dev->dev.bus_id); return 1; } @@ -511,23 +553,19 @@ int pnp_activate_dev(struct pnp_dev *dev) */ int pnp_disable_dev(struct pnp_dev *dev) { + int error; + if (!dev) return -EINVAL; if (!dev->active) { return 0; /* the device is already disabled */ } - if (!pnp_can_disable(dev)) { - pnp_info("Device %s does not supported disabling.", dev->dev.bus_id); - return -EINVAL; - } - if (dev->protocol->disable(dev)<0) { - pnp_err("Failed to disable device %s.", dev->dev.bus_id); - return -EIO; - } + error = pnp_stop_dev(dev); + if (error) + return error; dev->active = 0; - pnp_info("Device %s disabled.", dev->dev.bus_id); /* release the resources so that other devices can use them */ down(&pnp_res_mutex); @@ -558,6 +596,8 @@ EXPORT_SYMBOL(pnp_manual_config_dev); #if 0 EXPORT_SYMBOL(pnp_auto_config_dev); #endif +EXPORT_SYMBOL(pnp_start_dev); +EXPORT_SYMBOL(pnp_stop_dev); EXPORT_SYMBOL(pnp_activate_dev); EXPORT_SYMBOL(pnp_disable_dev); EXPORT_SYMBOL(pnp_resource_change); -- cgit v1.2.3 From 034382117725f6b6b26fbb138498139c5c012c1b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 11 Nov 2005 04:25:06 +0100 Subject: [PATCH] keep pnpbios usermod_helper away from hotplug_path[] These days we use udev to manage all kernel events. /proc/sys/kernel/hotplug will usually be disabled by an init-script. pnpnbios is not integrated with the driver core and should stay away from the now disabled /sbin/hotplug. Set the helper to /sbin/phpbios, even when there is probably no current user of this faciliy. If it's needed, it should definitely get proper driver core integration instead of forking binaries from the kernel. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/pnp/pnpbios/core.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/pnp') diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index f49674f07949..b154b3f52cbe 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -106,8 +105,6 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) char *argv [3], **envp, *buf, *scratch; int i = 0, value; - if (!hotplug_path [0]) - return -ENOENT; if (!current->fs->root) { return -EAGAIN; } @@ -119,8 +116,9 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) return -ENOMEM; } - /* only one standardized param to hotplug command: type */ - argv [0] = hotplug_path; + /* FIXME: if there are actual users of this, it should be integrated into + * the driver core and use the usual infrastructure like sysfs and uevents */ + argv [0] = "/sbin/pnpbios"; argv [1] = "dock"; argv [2] = NULL; -- cgit v1.2.3 From 7c4cb60e5b97677424e95baee9c29df54b26e6ba Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Fri, 6 Jan 2006 00:11:47 -0800 Subject: [PATCH] x86: GDT alignment fix Make GDT page aligned and page padded to support running inside of a hypervisor. This prevents false sharing of the GDT page with other hot data, which is not allowed in Xen, and causes performance problems in VMware. Rather than go back to the old method of statically allocating the GDT (which wastes unneded space for non-present CPUs), the GDT for APs is allocated dynamically. Signed-off-by: Zachary Amsden Cc: "Seth, Rohit" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/pnpbios/bioscalls.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers/pnp') diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 6b7583f497d0..7cb476ed7f91 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c @@ -69,14 +69,16 @@ __asm__( #define Q_SET_SEL(cpu, selname, address, size) \ do { \ -set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \ -set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ +struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ +set_base(gdt[(selname) >> 3], __va((u32)(address))); \ +set_limit(gdt[(selname) >> 3], size); \ } while(0) #define Q2_SET_SEL(cpu, selname, address, size) \ do { \ -set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \ -set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ +struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ +set_base(gdt[(selname) >> 3], (u32)(address)); \ +set_limit(gdt[(selname) >> 3], size); \ } while(0) static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; @@ -115,8 +117,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, return PNP_FUNCTION_NOT_SUPPORTED; cpu = get_cpu(); - save_desc_40 = per_cpu(cpu_gdt_table,cpu)[0x40 / 8]; - per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = bad_bios_desc; + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8]; + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; /* On some boxes IRQ's during PnP BIOS calls are deadly. */ spin_lock_irqsave(&pnp_bios_lock, flags); @@ -158,7 +160,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, ); spin_unlock_irqrestore(&pnp_bios_lock, flags); - per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = save_desc_40; + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40; put_cpu(); /* If we get here and this is set then the PnP BIOS faulted on us. */ @@ -535,8 +537,10 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header) set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); - for(i=0; i < NR_CPUS; i++) - { + for (i = 0; i < NR_CPUS; i++) { + struct desc_struct *gdt = get_cpu_gdt_table(i); + if (!gdt) + continue; Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024); Q_SET_SEL(i, PNP_CS16, header->fields.pm16cseg, 64 * 1024); Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024); -- cgit v1.2.3 From 5702d0f742b2f462267bca147334f77a255bcc74 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Fri, 6 Jan 2006 00:11:51 -0800 Subject: [PATCH] x86: Pnp segments in segment h Move PnP BIOS segment definitions into segment.h; the segments are reserved here, so they might as well be defined here as well. Note I didn't do this for APM BIOS, as Macintosh and other systems use those values to emulate APM in some scary way I don't want to understand. Signed-off-by: Zachary Amsden Acked-by: "Seth, Rohit" Cc: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/pnpbios/bioscalls.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/pnp') diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 7cb476ed7f91..37bacfcdbc5d 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c @@ -31,15 +31,6 @@ static struct { } pnp_bios_callpoint; -/* The PnP BIOS entries in the GDT */ -#define PNP_GDT (GDT_ENTRY_PNPBIOS_BASE * 8) - -#define PNP_CS32 (PNP_GDT+0x00) /* segment for calling fn */ -#define PNP_CS16 (PNP_GDT+0x08) /* code segment for BIOS */ -#define PNP_DS (PNP_GDT+0x10) /* data segment for BIOS */ -#define PNP_TS1 (PNP_GDT+0x18) /* transfer data segment */ -#define PNP_TS2 (PNP_GDT+0x20) /* another data segment */ - /* * These are some opcodes for a "static asmlinkage" * As this code is *not* executed inside the linux kernel segment, but in a -- cgit v1.2.3 From 5fe9fe3c6f9a1ae7aa224bb7a66eb9aad9e4abef Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Fri, 6 Jan 2006 00:11:55 -0800 Subject: [PATCH] x86: Pnp byte granularity The one remaining caller of set_limit, the PnP BIOS code, calls into the PnP BIOS, passing kernel parameters in and out. These parameteres may be passed from arbitrary kernel virtual memory, so they deserve strict protection to stop a bad BIOS from smashing beyond the object size. Unfortunately, the use of set_limit was badly botching this by setting the limit in terms of pages, when it really should have byte granularity. When doing this, I discovered my BIOS had the buggy code during the "get system device node" call: mov ax, es:[bx] Which is harmless, but has a trivial workaround. Signed-off-by: Zachary Amsden Cc: "Seth, Rohit" Cc: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/pnpbios/bioscalls.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/pnp') diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 37bacfcdbc5d..a72126180e97 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c @@ -283,12 +283,15 @@ int pnp_bios_dev_node_info(struct pnp_dev_node_info *data) static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) { u16 status; + u16 tmp_nodenum; if (!pnp_bios_present()) return PNP_FUNCTION_NOT_SUPPORTED; if ( !boot && pnpbios_dont_use_current_config ) return PNP_FUNCTION_NOT_SUPPORTED; + tmp_nodenum = *nodenum; status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0, - nodenum, sizeof(char), data, 65536); + &tmp_nodenum, sizeof(tmp_nodenum), data, 65536); + *nodenum = tmp_nodenum; return status; } -- cgit v1.2.3 From e6a9918c9617ed21f71f2f20b45efe06822c8f00 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Fri, 6 Jan 2006 00:11:56 -0800 Subject: [PATCH] x86: Fixed pnp bios limits PnP BIOS data, code, and 32-bit entry segments all have fixed limits as well; set them in the GDT rather than adding more code. It would be nice to add these fixups to the boot GDT rather than setting the GDT for each CPU; perhaps I can wiggle this in later, but getting it in before the subsys init looks tricky. Also, make some progress on deprecating the ugly Q_SET_SEL macros. Signed-off-by: Zachary Amsden Cc: "Seth, Rohit" Cc: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/pnpbios/bioscalls.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/pnp') diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index a72126180e97..a1f0b0ba2bfe 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c @@ -58,13 +58,6 @@ __asm__( ".previous \n" ); -#define Q_SET_SEL(cpu, selname, address, size) \ -do { \ -struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ -set_base(gdt[(selname) >> 3], __va((u32)(address))); \ -set_limit(gdt[(selname) >> 3], size); \ -} while(0) - #define Q2_SET_SEL(cpu, selname, address, size) \ do { \ struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ @@ -535,8 +528,8 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header) struct desc_struct *gdt = get_cpu_gdt_table(i); if (!gdt) continue; - Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024); - Q_SET_SEL(i, PNP_CS16, header->fields.pm16cseg, 64 * 1024); - Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024); - } + set_base(gdt[GDT_ENTRY_PNPBIOS_CS32], &pnp_bios_callfunc); + set_base(gdt[GDT_ENTRY_PNPBIOS_CS16], __va(header->fields.pm16cseg)); + set_base(gdt[GDT_ENTRY_PNPBIOS_DS], __va(header->fields.pm16dseg)); + } } -- cgit v1.2.3 From 6f957eaf79356a32e838f5f262ee9a60544b1d5b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 20 Sep 2005 15:26:00 -0400 Subject: [ACPI] enable PNPACPI support for resource types used by HP serial ports PNPACPI complained about and ignored devices with ADDRESS16, ADDRESS32, or ADDRESS64 descriptors in _PRS. HP firmware uses them for built-in serial ports, so this patch adds support for parsing these descriptors from _PRS. Note that this does not add the corresponding support for encoding them in preparation for _SRS, because I don't have any machine that supports _SRS on these descriptors, so I couldn't test that support. Attempts to encode them will cause a warning and an -EINVAL return. http://sourceforge.net/mailarchive/forum.php?thread_id=8250154&forum_id=6102 Signed-off-by: Bjorn Helgaas Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/rsparser.c | 48 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'drivers/pnp') diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 416d30debe6c..2424bd3620dc 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -453,6 +453,45 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, return; } +static void +pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r) +{ + struct acpi_resource_address64 addr, *p = &addr; + acpi_status status; + struct pnp_mem * mem; + struct pnp_port * port; + + status = acpi_resource_to_address64(r, p); + if (!ACPI_SUCCESS(status)) { + pnp_warn("PnPACPI: failed to convert resource type %d", r->id); + return; + } + + if (p->address_length == 0) + return; + + if (p->resource_type == ACPI_MEMORY_RANGE) { + mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL); + if (!mem) + return; + mem->min = mem->max = p->min_address_range; + mem->size = p->address_length; + mem->align = 0; + mem->flags = (p->attribute.memory.read_write_attribute == + ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0; + pnp_register_mem_resource(option,mem); + } else if (p->resource_type == ACPI_IO_RANGE) { + port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL); + if (!port) + return; + port->min = port->max = p->min_address_range; + port->size = p->address_length; + port->align = 0; + port->flags = PNP_PORT_FLAG_FIXED; + pnp_register_port_resource(option,port); + } +} + struct acpipnp_parse_option_s { struct pnp_option *option; struct pnp_option *option_independent; @@ -495,6 +534,11 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, pnpacpi_parse_fixed_mem32_option(option, &res->data.fixed_memory32); break; + case ACPI_RSTYPE_ADDRESS16: + case ACPI_RSTYPE_ADDRESS32: + case ACPI_RSTYPE_ADDRESS64: + pnpacpi_parse_address_option(option, res); + break; case ACPI_RSTYPE_START_DPF: switch (res->data.start_dpf.compatibility_priority) { case ACPI_GOOD_CONFIGURATION: @@ -568,11 +612,9 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, case ACPI_RSTYPE_MEM24: case ACPI_RSTYPE_MEM32: case ACPI_RSTYPE_FIXED_MEM32: -#if 0 case ACPI_RSTYPE_ADDRESS16: case ACPI_RSTYPE_ADDRESS32: case ACPI_RSTYPE_ADDRESS64: -#endif (*res_cnt) ++; default: return AE_OK; @@ -593,11 +635,9 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, case ACPI_RSTYPE_MEM24: case ACPI_RSTYPE_MEM32: case ACPI_RSTYPE_FIXED_MEM32: -#if 0 case ACPI_RSTYPE_ADDRESS16: case ACPI_RSTYPE_ADDRESS32: case ACPI_RSTYPE_ADDRESS64: -#endif (*resource)->id = res->id; (*resource)++; default: -- cgit v1.2.3