From: Witold Szczeponik <Witold.Szczeponik@gmx.net>
To: "linux-acpi@vger.kernel.org" <linux-acpi@vger.kernel.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Bjorn Helgaas <bjorn.helgaas@hp.com>
Subject: [PATCH] PNPACPI: Register disabled resources
Date: Fri, 24 Jun 2011 23:02:33 +0200 [thread overview]
Message-ID: <4E04FB69.3000206@gmx.net> (raw)
When parsing PnP resources, it may happen that some of these
are disabled. The current solution is to skip these resources
completely - with the unfortunate side effect that they are not
registered despite the fact that they exist, after all. The
downside of his is that these resources cannot be manipulated
programatically. The kernel's APM implementation does not suffer
from this problem.
This patch fixes a problem with (at least) some vintage IBM
ThinkPad 600E (and most likely also on the 600, 600X, and 770X
which have a very similar layout) where some of its PnP devices
support options where either an IRQ or DMA is disabled. The
manipulation of these resources is important because the 600E
has very special requirements.
The patch applies the idea to register disabled resources to
all types of resources, not just to IRQs and DMAs.
No regressions were observed on hardware that does not require
this patch.
The patch is applied against 2.6.39.
Signed-off-by: Witold Szczeponik <Witold.Szczeponik@gmx.net>
Index: linux/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- linux.orig/drivers/pnp/pnpacpi/rsparser.c
+++ linux/drivers/pnp/pnpacpi/rsparser.c
@@ -509,15 +509,15 @@ static __init void pnpacpi_parse_dma_opt
struct acpi_resource_dma *p)
{
int i;
- unsigned char map = 0, flags;
+ unsigned char map = 0, flags = 0;
if (p->channel_count == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
for (i = 0; i < p->channel_count; i++)
map |= 1 << p->channels[i];
- flags = dma_flags(dev, p->type, p->bus_master, p->transfer);
+ flags |= dma_flags(dev, p->type, p->bus_master, p->transfer);
pnp_register_dma_resource(dev, option_flags, map, flags);
}
@@ -527,17 +527,17 @@ static __init void pnpacpi_parse_irq_opt
{
int i;
pnp_irq_mask_t map;
- unsigned char flags;
+ unsigned char flags = 0;
if (p->interrupt_count == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
bitmap_zero(map.bits, PNP_IRQ_NR);
for (i = 0; i < p->interrupt_count; i++)
if (p->interrupts[i])
__set_bit(p->interrupts[i], map.bits);
- flags = irq_flags(p->triggering, p->polarity, p->sharable);
+ flags |= irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option_flags, &map, flags);
}
@@ -547,10 +547,10 @@ static __init void pnpacpi_parse_ext_irq
{
int i;
pnp_irq_mask_t map;
- unsigned char flags;
+ unsigned char flags = 0;
if (p->interrupt_count == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
bitmap_zero(map.bits, PNP_IRQ_NR);
for (i = 0; i < p->interrupt_count; i++) {
@@ -564,7 +564,7 @@ static __init void pnpacpi_parse_ext_irq
}
}
- flags = irq_flags(p->triggering, p->polarity, p->sharable);
+ flags |= irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option_flags, &map, flags);
}
@@ -575,10 +575,10 @@ static __init void pnpacpi_parse_port_op
unsigned char flags = 0;
if (io->address_length == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
if (io->io_decode == ACPI_DECODE_16)
- flags = IORESOURCE_IO_16BIT_ADDR;
+ flags |= IORESOURCE_IO_16BIT_ADDR;
pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
io->alignment, io->address_length, flags);
}
@@ -587,11 +587,13 @@ static __init void pnpacpi_parse_fixed_p
unsigned int option_flags,
struct acpi_resource_fixed_io *io)
{
+ unsigned char flags = 0;
+
if (io->address_length == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
pnp_register_port_resource(dev, option_flags, io->address, io->address,
- 0, io->address_length, IORESOURCE_IO_FIXED);
+ 0, io->address_length, flags | IORESOURCE_IO_FIXED);
}
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
@@ -601,10 +603,10 @@ static __init void pnpacpi_parse_mem24_o
unsigned char flags = 0;
if (p->address_length == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
if (p->write_protect == ACPI_READ_WRITE_MEMORY)
- flags = IORESOURCE_MEM_WRITEABLE;
+ flags |= IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
p->alignment, p->address_length, flags);
}
@@ -616,10 +618,10 @@ static __init void pnpacpi_parse_mem32_o
unsigned char flags = 0;
if (p->address_length == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
if (p->write_protect == ACPI_READ_WRITE_MEMORY)
- flags = IORESOURCE_MEM_WRITEABLE;
+ flags |= IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
p->alignment, p->address_length, flags);
}
@@ -631,10 +633,10 @@ static __init void pnpacpi_parse_fixed_m
unsigned char flags = 0;
if (p->address_length == 0)
- return;
+ iflags |= IORESOURCE_DISABLED;
if (p->write_protect == ACPI_READ_WRITE_MEMORY)
- flags = IORESOURCE_MEM_WRITEABLE;
+ flags |= IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->address, p->address,
0, p->address_length, flags);
}
@@ -655,18 +657,18 @@ static __init void pnpacpi_parse_address
}
if (p->address_length == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
if (p->resource_type == ACPI_MEMORY_RANGE) {
if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
- flags = IORESOURCE_MEM_WRITEABLE;
+ flags |= IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->minimum,
p->minimum, 0, p->address_length,
flags);
} else if (p->resource_type == ACPI_IO_RANGE)
pnp_register_port_resource(dev, option_flags, p->minimum,
p->minimum, 0, p->address_length,
- IORESOURCE_IO_FIXED);
+ flags | IORESOURCE_IO_FIXED);
}
static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev,
@@ -677,18 +679,18 @@ static __init void pnpacpi_parse_ext_add
unsigned char flags = 0;
if (p->address_length == 0)
- return;
+ flags |= IORESOURCE_DISABLED;
if (p->resource_type == ACPI_MEMORY_RANGE) {
if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
- flags = IORESOURCE_MEM_WRITEABLE;
+ flags |= IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->minimum,
p->minimum, 0, p->address_length,
flags);
} else if (p->resource_type == ACPI_IO_RANGE)
pnp_register_port_resource(dev, option_flags, p->minimum,
p->minimum, 0, p->address_length,
- IORESOURCE_IO_FIXED);
+ flags | IORESOURCE_IO_FIXED);
}
struct acpipnp_parse_option_s {
next reply other threads:[~2011-06-24 21:02 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-24 21:02 Witold Szczeponik [this message]
2011-06-25 2:54 ` [PATCH] PNPACPI: Register disabled resources Henrique de Moraes Holschuh
2011-07-03 10:50 ` Witold Szczeponik
2011-07-03 11:32 ` [PATCH v2] " Witold Szczeponik
2011-07-03 11:50 ` Henrique de Moraes Holschuh
2011-07-31 12:47 ` [PATCH v3] PNPACPI: Register disabled/empty resources Witold Szczeponik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E04FB69.3000206@gmx.net \
--to=witold.szczeponik@gmx.net \
--cc=bjorn.helgaas@hp.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox