diff options
Diffstat (limited to 'drivers/pnp/pnpacpi/rsparser.c')
| -rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 138 |
1 files changed, 78 insertions, 60 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 9847ab163829..c02ce0834c2c 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * pnpacpi -- PnP ACPI driver * @@ -5,20 +6,6 @@ * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. * Bjorn Helgaas <bjorn.helgaas@hp.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/kernel.h> #include <linux/acpi.h> @@ -28,8 +15,8 @@ #include "../base.h" #include "pnpacpi.h" -static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, - int *polarity, int *shareable) +static void decode_irq_flags(struct pnp_dev *dev, int flags, u8 *triggering, + u8 *polarity, u8 *shareable) { switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) { @@ -149,8 +136,8 @@ static int vendor_resource_matches(struct pnp_dev *dev, uuid_len == sizeof(match->data) && memcmp(uuid, match->data, uuid_len) == 0) { if (expected_len && expected_len != actual_len) { - dev_err(&dev->dev, "wrong vendor descriptor size; " - "expected %d, found %d bytes\n", + dev_err(&dev->dev, + "wrong vendor descriptor size; expected %d, found %d bytes\n", expected_len, actual_len); return 0; } @@ -164,13 +151,13 @@ static int vendor_resource_matches(struct pnp_dev *dev, static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, struct acpi_resource_vendor_typed *vendor) { - if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) { - u64 start, length; - - memcpy(&start, vendor->byte_data, sizeof(start)); - memcpy(&length, vendor->byte_data + 8, sizeof(length)); + struct { u64 start, length; } range; - pnp_add_mem_resource(dev, start, start + length - 1, 0); + if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, + sizeof(range))) { + memcpy(&range, vendor->byte_data, sizeof(range)); + pnp_add_mem_resource(dev, range.start, range.start + + range.length - 1, 0); } } @@ -180,22 +167,22 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, struct pnp_dev *dev = data; struct acpi_resource_dma *dma; struct acpi_resource_vendor_typed *vendor_typed; - struct resource r; + struct acpi_resource_gpio *gpio; + struct resource_win win = {{0}, 0}; + struct resource *r = &win.res; int i, flags; - if (acpi_dev_resource_memory(res, &r) - || acpi_dev_resource_io(res, &r) - || acpi_dev_resource_address_space(res, &r) - || acpi_dev_resource_ext_address_space(res, &r)) { - pnp_add_resource(dev, &r); + if (acpi_dev_resource_address_space(res, &win) + || acpi_dev_resource_ext_address_space(res, &win)) { + pnp_add_resource(dev, &win.res); return AE_OK; } - r.flags = 0; - if (acpi_dev_resource_interrupt(res, 0, &r)) { - pnpacpi_add_irqresource(dev, &r); - for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++) - pnpacpi_add_irqresource(dev, &r); + r->flags = 0; + if (acpi_dev_resource_interrupt(res, 0, r)) { + pnpacpi_add_irqresource(dev, r); + for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++) + pnpacpi_add_irqresource(dev, r); if (i > 1) { /* @@ -204,19 +191,45 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, * one interrupt, we won't be able to re-encode it. */ if (pnp_can_write(dev)) { - dev_warn(&dev->dev, "multiple interrupts in " - "_CRS descriptor; configuration can't " - "be changed\n"); + dev_warn(&dev->dev, + "multiple interrupts in _CRS descriptor; configuration can't be changed\n"); dev->capabilities &= ~PNP_WRITE; } } return AE_OK; - } else if (r.flags & IORESOURCE_DISABLED) { + } else if (acpi_gpio_get_irq_resource(res, &gpio)) { + /* + * If the resource is GpioInt() type then extract the IRQ + * from GPIO resource and fill it into IRQ resource type. + */ + i = acpi_dev_gpio_irq_get(dev->data, 0); + if (i >= 0) { + flags = acpi_dev_irq_flags(gpio->triggering, + gpio->polarity, + gpio->shareable, + gpio->wake_capable); + } else { + flags = IORESOURCE_DISABLED; + } + pnp_add_irq_resource(dev, i, flags); + return AE_OK; + } else if (r->flags & IORESOURCE_DISABLED) { pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); return AE_OK; } switch (res->type) { + case ACPI_RESOURCE_TYPE_MEMORY24: + case ACPI_RESOURCE_TYPE_MEMORY32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + if (acpi_dev_resource_memory(res, r)) + pnp_add_resource(dev, r); + break; + case ACPI_RESOURCE_TYPE_IO: + case ACPI_RESOURCE_TYPE_FIXED_IO: + if (acpi_dev_resource_io(res, r)) + pnp_add_resource(dev, r); + break; case ACPI_RESOURCE_TYPE_DMA: dma = &res->data.dma; if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) @@ -242,6 +255,10 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: break; + case ACPI_RESOURCE_TYPE_SERIAL_BUS: + /* serial bus connections (I2C/SPI/UART) are not pnp */ + break; + default: dev_warn(&dev->dev, "unknown resource type %d in _CRS\n", res->type); @@ -299,7 +316,7 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, if (p->interrupts[i]) __set_bit(p->interrupts[i], map.bits); - flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable); + flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->shareable, p->wake_capable); pnp_register_irq_resource(dev, option_flags, &map, flags); } @@ -317,13 +334,13 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, if (p->interrupts[i] < PNP_IRQ_NR) __set_bit(p->interrupts[i], map.bits); else - dev_err(&dev->dev, "ignoring IRQ %d option " - "(too large for %d entry bitmap)\n", + dev_err(&dev->dev, + "ignoring IRQ %d option (too large for %d entry bitmap)\n", p->interrupts[i], PNP_IRQ_NR); } } - flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable); + flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->shareable, p->wake_capable); pnp_register_irq_resource(dev, option_flags, &map, flags); } @@ -401,12 +418,12 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, if (p->resource_type == ACPI_MEMORY_RANGE) { if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) flags = IORESOURCE_MEM_WRITEABLE; - pnp_register_mem_resource(dev, option_flags, p->minimum, - p->minimum, 0, p->address_length, + pnp_register_mem_resource(dev, option_flags, p->address.minimum, + p->address.minimum, 0, p->address.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, + pnp_register_port_resource(dev, option_flags, p->address.minimum, + p->address.minimum, 0, p->address.address_length, IORESOURCE_IO_FIXED); } @@ -420,12 +437,12 @@ static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev, if (p->resource_type == ACPI_MEMORY_RANGE) { if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) flags = IORESOURCE_MEM_WRITEABLE; - pnp_register_mem_resource(dev, option_flags, p->minimum, - p->minimum, 0, p->address_length, + pnp_register_mem_resource(dev, option_flags, p->address.minimum, + p->address.minimum, 0, p->address.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, + pnp_register_port_resource(dev, option_flags, p->address.minimum, + p->address.minimum, 0, p->address.address_length, IORESOURCE_IO_FIXED); } @@ -644,7 +661,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, struct resource *p) { struct acpi_resource_irq *irq = &resource->data.irq; - int triggering, polarity, shareable; + u8 triggering, polarity, shareable; if (!pnp_resource_enabled(p)) { irq->interrupt_count = 0; @@ -656,7 +673,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); irq->triggering = triggering; irq->polarity = polarity; - irq->sharable = shareable; + irq->shareable = shareable; irq->interrupt_count = 1; irq->interrupts[0] = p->start; @@ -664,7 +681,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, (int) p->start, triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", polarity == ACPI_ACTIVE_LOW ? "low" : "high", - irq->sharable == ACPI_SHARED ? "shared" : "exclusive", + irq->shareable == ACPI_SHARED ? "shared" : "exclusive", irq->descriptor_length); } @@ -673,7 +690,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, struct resource *p) { struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; - int triggering, polarity, shareable; + u8 triggering, polarity, shareable; if (!pnp_resource_enabled(p)) { extended_irq->interrupt_count = 0; @@ -686,14 +703,14 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, extended_irq->producer_consumer = ACPI_CONSUMER; extended_irq->triggering = triggering; extended_irq->polarity = polarity; - extended_irq->sharable = shareable; + extended_irq->shareable = shareable; extended_irq->interrupt_count = 1; extended_irq->interrupts[0] = p->start; pnp_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", polarity == ACPI_ACTIVE_LOW ? "low" : "high", - extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); + extended_irq->shareable == ACPI_SHARED ? "shared" : "exclusive"); } static void pnpacpi_encode_dma(struct pnp_dev *dev, @@ -863,7 +880,7 @@ int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer) /* pnpacpi_build_resource_template allocates extra mem */ int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1; struct acpi_resource *resource = buffer->pointer; - int port = 0, irq = 0, dma = 0, mem = 0; + unsigned int port = 0, irq = 0, dma = 0, mem = 0; pnp_dbg(&dev->dev, "encode %d resources\n", res_cnt); while (i < res_cnt) { @@ -919,8 +936,9 @@ int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer) case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: default: /* other type */ - dev_warn(&dev->dev, "can't encode unknown resource " - "type %d\n", resource->type); + dev_warn(&dev->dev, + "can't encode unknown resource type %d\n", + resource->type); return -EINVAL; } resource++; |
