xref: /linux/drivers/pnp/pnpacpi/rsparser.c (revision 06d07429858317ded2db7986113a9e0129cd599b)
13e0a4e85SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * pnpacpi -- PnP ACPI driver
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
61da177e4SLinus Torvalds  * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
740ab4f4cSBjorn Helgaas  * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
840ab4f4cSBjorn Helgaas  *	Bjorn Helgaas <bjorn.helgaas@hp.com>
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds #include <linux/kernel.h>
111da177e4SLinus Torvalds #include <linux/acpi.h>
121da177e4SLinus Torvalds #include <linux/pci.h>
1302d83b5dSBjorn Helgaas #include <linux/pnp.h>
145a0e3ad6STejun Heo #include <linux/slab.h>
1502d83b5dSBjorn Helgaas #include "../base.h"
161da177e4SLinus Torvalds #include "pnpacpi.h"
171da177e4SLinus Torvalds 
decode_irq_flags(struct pnp_dev * dev,int flags,u8 * triggering,u8 * polarity,u8 * shareable)18bbee06d0SFabian Frederick static void decode_irq_flags(struct pnp_dev *dev, int flags, u8 *triggering,
19bbee06d0SFabian Frederick 			     u8 *polarity, u8 *shareable)
201da177e4SLinus Torvalds {
21e9fe9e18SBjorn Helgaas 	switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL |
22e9fe9e18SBjorn Helgaas 			 IORESOURCE_IRQ_LOWEDGE  | IORESOURCE_IRQ_HIGHEDGE)) {
231da177e4SLinus Torvalds 	case IORESOURCE_IRQ_LOWLEVEL:
2450eca3ebSBob Moore 		*triggering = ACPI_LEVEL_SENSITIVE;
2550eca3ebSBob Moore 		*polarity = ACPI_ACTIVE_LOW;
261da177e4SLinus Torvalds 		break;
271da177e4SLinus Torvalds 	case IORESOURCE_IRQ_HIGHLEVEL:
2850eca3ebSBob Moore 		*triggering = ACPI_LEVEL_SENSITIVE;
2950eca3ebSBob Moore 		*polarity = ACPI_ACTIVE_HIGH;
301da177e4SLinus Torvalds 		break;
311da177e4SLinus Torvalds 	case IORESOURCE_IRQ_LOWEDGE:
3250eca3ebSBob Moore 		*triggering = ACPI_EDGE_SENSITIVE;
3350eca3ebSBob Moore 		*polarity = ACPI_ACTIVE_LOW;
341da177e4SLinus Torvalds 		break;
351da177e4SLinus Torvalds 	case IORESOURCE_IRQ_HIGHEDGE:
3650eca3ebSBob Moore 		*triggering = ACPI_EDGE_SENSITIVE;
3750eca3ebSBob Moore 		*polarity = ACPI_ACTIVE_HIGH;
381da177e4SLinus Torvalds 		break;
39e9fe9e18SBjorn Helgaas 	default:
40e9fe9e18SBjorn Helgaas 		dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n",
41e9fe9e18SBjorn Helgaas 			flags);
42e9fe9e18SBjorn Helgaas 		*triggering = ACPI_EDGE_SENSITIVE;
43e9fe9e18SBjorn Helgaas 		*polarity = ACPI_ACTIVE_HIGH;
44e9fe9e18SBjorn Helgaas 		break;
451da177e4SLinus Torvalds 	}
46a993273bSBjorn Helgaas 
47a993273bSBjorn Helgaas 	if (flags & IORESOURCE_IRQ_SHAREABLE)
48a993273bSBjorn Helgaas 		*shareable = ACPI_SHARED;
49a993273bSBjorn Helgaas 	else
50a993273bSBjorn Helgaas 		*shareable = ACPI_EXCLUSIVE;
511da177e4SLinus Torvalds }
521da177e4SLinus Torvalds 
dma_flags(struct pnp_dev * dev,int type,int bus_master,int transfer)53958a1fddSBjorn Helgaas static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
54958a1fddSBjorn Helgaas 		     int transfer)
55362ea087SMichael Karcher {
56362ea087SMichael Karcher 	int flags = 0;
57362ea087SMichael Karcher 
58362ea087SMichael Karcher 	if (bus_master)
59362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_MASTER;
60362ea087SMichael Karcher 	switch (type) {
61362ea087SMichael Karcher 	case ACPI_COMPATIBILITY:
62362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_COMPATIBLE;
63362ea087SMichael Karcher 		break;
64362ea087SMichael Karcher 	case ACPI_TYPE_A:
65362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_TYPEA;
66362ea087SMichael Karcher 		break;
67362ea087SMichael Karcher 	case ACPI_TYPE_B:
68362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_TYPEB;
69362ea087SMichael Karcher 		break;
70362ea087SMichael Karcher 	case ACPI_TYPE_F:
71362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_TYPEF;
72362ea087SMichael Karcher 		break;
73362ea087SMichael Karcher 	default:
74362ea087SMichael Karcher 		/* Set a default value ? */
75362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_COMPATIBLE;
76958a1fddSBjorn Helgaas 		dev_err(&dev->dev, "invalid DMA type %d\n", type);
77362ea087SMichael Karcher 	}
78362ea087SMichael Karcher 	switch (transfer) {
79362ea087SMichael Karcher 	case ACPI_TRANSFER_8:
80362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_8BIT;
81362ea087SMichael Karcher 		break;
82362ea087SMichael Karcher 	case ACPI_TRANSFER_8_16:
83362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_8AND16BIT;
84362ea087SMichael Karcher 		break;
85362ea087SMichael Karcher 	case ACPI_TRANSFER_16:
86362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_16BIT;
87362ea087SMichael Karcher 		break;
88362ea087SMichael Karcher 	default:
89362ea087SMichael Karcher 		/* Set a default value ? */
90362ea087SMichael Karcher 		flags |= IORESOURCE_DMA_8AND16BIT;
91958a1fddSBjorn Helgaas 		dev_err(&dev->dev, "invalid DMA transfer type %d\n", transfer);
92362ea087SMichael Karcher 	}
93362ea087SMichael Karcher 
94362ea087SMichael Karcher 	return flags;
95362ea087SMichael Karcher }
96362ea087SMichael Karcher 
97046d9ce6SRafael J. Wysocki /*
98046d9ce6SRafael J. Wysocki  * Allocated Resources
99046d9ce6SRafael J. Wysocki  */
100046d9ce6SRafael J. Wysocki 
pnpacpi_add_irqresource(struct pnp_dev * dev,struct resource * r)101046d9ce6SRafael J. Wysocki static void pnpacpi_add_irqresource(struct pnp_dev *dev, struct resource *r)
1021da177e4SLinus Torvalds {
103046d9ce6SRafael J. Wysocki 	if (!(r->flags & IORESOURCE_DISABLED))
104046d9ce6SRafael J. Wysocki 		pcibios_penalize_isa_irq(r->start, 1);
10507d4e9afSBjorn Helgaas 
106046d9ce6SRafael J. Wysocki 	pnp_add_resource(dev, r);
1071da177e4SLinus Torvalds }
1081da177e4SLinus Torvalds 
10940ab4f4cSBjorn Helgaas /*
11040ab4f4cSBjorn Helgaas  * Device CSRs that do not appear in PCI config space should be described
11140ab4f4cSBjorn Helgaas  * via ACPI.  This would normally be done with Address Space Descriptors
11240ab4f4cSBjorn Helgaas  * marked as "consumer-only," but old versions of Windows and Linux ignore
11340ab4f4cSBjorn Helgaas  * the producer/consumer flag, so HP invented a vendor-defined resource to
11440ab4f4cSBjorn Helgaas  * describe the location and size of CSR space.
11540ab4f4cSBjorn Helgaas  */
11640ab4f4cSBjorn Helgaas static struct acpi_vendor_uuid hp_ccsr_uuid = {
11740ab4f4cSBjorn Helgaas 	.subtype = 2,
11840ab4f4cSBjorn Helgaas 	.data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
11940ab4f4cSBjorn Helgaas 	    0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
12040ab4f4cSBjorn Helgaas };
12140ab4f4cSBjorn Helgaas 
vendor_resource_matches(struct pnp_dev * dev,struct acpi_resource_vendor_typed * vendor,struct acpi_vendor_uuid * match,int expected_len)12240ab4f4cSBjorn Helgaas static int vendor_resource_matches(struct pnp_dev *dev,
12340ab4f4cSBjorn Helgaas 				   struct acpi_resource_vendor_typed *vendor,
12440ab4f4cSBjorn Helgaas 				   struct acpi_vendor_uuid *match,
12540ab4f4cSBjorn Helgaas 				   int expected_len)
12640ab4f4cSBjorn Helgaas {
12740ab4f4cSBjorn Helgaas 	int uuid_len = sizeof(vendor->uuid);
12840ab4f4cSBjorn Helgaas 	u8 uuid_subtype = vendor->uuid_subtype;
12940ab4f4cSBjorn Helgaas 	u8 *uuid = vendor->uuid;
13040ab4f4cSBjorn Helgaas 	int actual_len;
13140ab4f4cSBjorn Helgaas 
13240ab4f4cSBjorn Helgaas 	/* byte_length includes uuid_subtype and uuid */
13340ab4f4cSBjorn Helgaas 	actual_len = vendor->byte_length - uuid_len - 1;
13440ab4f4cSBjorn Helgaas 
13540ab4f4cSBjorn Helgaas 	if (uuid_subtype == match->subtype &&
13640ab4f4cSBjorn Helgaas 	    uuid_len == sizeof(match->data) &&
13740ab4f4cSBjorn Helgaas 	    memcmp(uuid, match->data, uuid_len) == 0) {
13840ab4f4cSBjorn Helgaas 		if (expected_len && expected_len != actual_len) {
1391d7f2cddSAndy Shevchenko 			dev_err(&dev->dev,
1401d7f2cddSAndy Shevchenko 				"wrong vendor descriptor size; expected %d, found %d bytes\n",
14140ab4f4cSBjorn Helgaas 				expected_len, actual_len);
14240ab4f4cSBjorn Helgaas 			return 0;
14340ab4f4cSBjorn Helgaas 		}
14440ab4f4cSBjorn Helgaas 
14540ab4f4cSBjorn Helgaas 		return 1;
14640ab4f4cSBjorn Helgaas 	}
14740ab4f4cSBjorn Helgaas 
14840ab4f4cSBjorn Helgaas 	return 0;
14940ab4f4cSBjorn Helgaas }
15040ab4f4cSBjorn Helgaas 
pnpacpi_parse_allocated_vendor(struct pnp_dev * dev,struct acpi_resource_vendor_typed * vendor)15140ab4f4cSBjorn Helgaas static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev,
15240ab4f4cSBjorn Helgaas 				    struct acpi_resource_vendor_typed *vendor)
15340ab4f4cSBjorn Helgaas {
154*ba3f5058SDmitry Antipov 	struct { u64 start, length; } range;
15540ab4f4cSBjorn Helgaas 
156*ba3f5058SDmitry Antipov 	if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid,
157*ba3f5058SDmitry Antipov 				    sizeof(range))) {
158*ba3f5058SDmitry Antipov 		memcpy(&range, vendor->byte_data, sizeof(range));
159*ba3f5058SDmitry Antipov 		pnp_add_mem_resource(dev, range.start, range.start +
160*ba3f5058SDmitry Antipov 				     range.length - 1, 0);
16140ab4f4cSBjorn Helgaas 	}
16240ab4f4cSBjorn Helgaas }
16340ab4f4cSBjorn Helgaas 
pnpacpi_allocated_resource(struct acpi_resource * res,void * data)1641da177e4SLinus Torvalds static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
1651da177e4SLinus Torvalds 					      void *data)
1661da177e4SLinus Torvalds {
1674ab55d8dSBjorn Helgaas 	struct pnp_dev *dev = data;
1689570a20eSBjorn Helgaas 	struct acpi_resource_dma *dma;
16940ab4f4cSBjorn Helgaas 	struct acpi_resource_vendor_typed *vendor_typed;
1702a56e919SJagadish Krishnamoorthy 	struct acpi_resource_gpio *gpio;
171a49170b5SJiang Liu 	struct resource_win win = {{0}, 0};
172a49170b5SJiang Liu 	struct resource *r = &win.res;
173dc16f5f2SBjorn Helgaas 	int i, flags;
1741da177e4SLinus Torvalds 
175a49170b5SJiang Liu 	if (acpi_dev_resource_address_space(res, &win)
176a49170b5SJiang Liu 	    || acpi_dev_resource_ext_address_space(res, &win)) {
177a49170b5SJiang Liu 		pnp_add_resource(dev, &win.res);
178046d9ce6SRafael J. Wysocki 		return AE_OK;
1791da177e4SLinus Torvalds 	}
1805acf9141SBjorn Helgaas 
181a49170b5SJiang Liu 	r->flags = 0;
182a49170b5SJiang Liu 	if (acpi_dev_resource_interrupt(res, 0, r)) {
183a49170b5SJiang Liu 		pnpacpi_add_irqresource(dev, r);
184a49170b5SJiang Liu 		for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++)
185a49170b5SJiang Liu 			pnpacpi_add_irqresource(dev, r);
186046d9ce6SRafael J. Wysocki 
187046d9ce6SRafael J. Wysocki 		if (i > 1) {
1885acf9141SBjorn Helgaas 			/*
1895acf9141SBjorn Helgaas 			 * The IRQ encoder puts a single interrupt in each
1905acf9141SBjorn Helgaas 			 * descriptor, so if a _CRS descriptor has more than
1915acf9141SBjorn Helgaas 			 * one interrupt, we won't be able to re-encode it.
1925acf9141SBjorn Helgaas 			 */
193046d9ce6SRafael J. Wysocki 			if (pnp_can_write(dev)) {
1941d7f2cddSAndy Shevchenko 				dev_warn(&dev->dev,
1951d7f2cddSAndy Shevchenko 					 "multiple interrupts in _CRS descriptor; configuration can't be changed\n");
1965acf9141SBjorn Helgaas 				dev->capabilities &= ~PNP_WRITE;
1975acf9141SBjorn Helgaas 			}
1985acf9141SBjorn Helgaas 		}
199046d9ce6SRafael J. Wysocki 		return AE_OK;
2002a56e919SJagadish Krishnamoorthy 	} else if (acpi_gpio_get_irq_resource(res, &gpio)) {
2012a56e919SJagadish Krishnamoorthy 		/*
2022a56e919SJagadish Krishnamoorthy 		 * If the resource is GpioInt() type then extract the IRQ
2032a56e919SJagadish Krishnamoorthy 		 * from GPIO resource and fill it into IRQ resource type.
2042a56e919SJagadish Krishnamoorthy 		 */
2052a56e919SJagadish Krishnamoorthy 		i = acpi_dev_gpio_irq_get(dev->data, 0);
2062a56e919SJagadish Krishnamoorthy 		if (i >= 0) {
2072a56e919SJagadish Krishnamoorthy 			flags = acpi_dev_irq_flags(gpio->triggering,
2082a56e919SJagadish Krishnamoorthy 						   gpio->polarity,
2095ff81160SRaul E Rangel 						   gpio->shareable,
2105ff81160SRaul E Rangel 						   gpio->wake_capable);
2112a56e919SJagadish Krishnamoorthy 		} else {
2122a56e919SJagadish Krishnamoorthy 			flags = IORESOURCE_DISABLED;
2132a56e919SJagadish Krishnamoorthy 		}
2142a56e919SJagadish Krishnamoorthy 		pnp_add_irq_resource(dev, i, flags);
2152a56e919SJagadish Krishnamoorthy 		return AE_OK;
216a49170b5SJiang Liu 	} else if (r->flags & IORESOURCE_DISABLED) {
217046d9ce6SRafael J. Wysocki 		pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
218046d9ce6SRafael J. Wysocki 		return AE_OK;
219046d9ce6SRafael J. Wysocki 	}
2201da177e4SLinus Torvalds 
221046d9ce6SRafael J. Wysocki 	switch (res->type) {
22289935315SZhang Rui 	case ACPI_RESOURCE_TYPE_MEMORY24:
22389935315SZhang Rui 	case ACPI_RESOURCE_TYPE_MEMORY32:
22489935315SZhang Rui 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
225a49170b5SJiang Liu 		if (acpi_dev_resource_memory(res, r))
226a49170b5SJiang Liu 			pnp_add_resource(dev, r);
22789935315SZhang Rui 		break;
22889935315SZhang Rui 	case ACPI_RESOURCE_TYPE_IO:
22989935315SZhang Rui 	case ACPI_RESOURCE_TYPE_FIXED_IO:
230a49170b5SJiang Liu 		if (acpi_dev_resource_io(res, r))
231a49170b5SJiang Liu 			pnp_add_resource(dev, r);
23289935315SZhang Rui 		break;
23350eca3ebSBob Moore 	case ACPI_RESOURCE_TYPE_DMA:
2349570a20eSBjorn Helgaas 		dma = &res->data.dma;
2355acf9141SBjorn Helgaas 		if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
236958a1fddSBjorn Helgaas 			flags = dma_flags(dev, dma->type, dma->bus_master,
237dc16f5f2SBjorn Helgaas 					  dma->transfer);
2385acf9141SBjorn Helgaas 		else
2395acf9141SBjorn Helgaas 			flags = IORESOURCE_DISABLED;
240dc16f5f2SBjorn Helgaas 		pnp_add_dma_resource(dev, dma->channels[0], flags);
2411da177e4SLinus Torvalds 		break;
2420af5853bSLen Brown 
2430af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
2440af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
2450af5853bSLen Brown 		break;
2460af5853bSLen Brown 
2470af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_VENDOR:
24840ab4f4cSBjorn Helgaas 		vendor_typed = &res->data.vendor_typed;
24940ab4f4cSBjorn Helgaas 		pnpacpi_parse_allocated_vendor(dev, vendor_typed);
2500af5853bSLen Brown 		break;
2510af5853bSLen Brown 
2520af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_END_TAG:
2530af5853bSLen Brown 		break;
2540af5853bSLen Brown 
2550af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
2560af5853bSLen Brown 		break;
2570af5853bSLen Brown 
25886e75410SHarb Abdulhamid 	case ACPI_RESOURCE_TYPE_SERIAL_BUS:
25986e75410SHarb Abdulhamid 		/* serial bus connections (I2C/SPI/UART) are not pnp */
26086e75410SHarb Abdulhamid 		break;
26186e75410SHarb Abdulhamid 
2621da177e4SLinus Torvalds 	default:
263af11cb2dSBjorn Helgaas 		dev_warn(&dev->dev, "unknown resource type %d in _CRS\n",
264af11cb2dSBjorn Helgaas 			 res->type);
2651da177e4SLinus Torvalds 		return AE_ERROR;
2661da177e4SLinus Torvalds 	}
2671da177e4SLinus Torvalds 
2681da177e4SLinus Torvalds 	return AE_OK;
2691da177e4SLinus Torvalds }
2701da177e4SLinus Torvalds 
pnpacpi_parse_allocated_resource(struct pnp_dev * dev)271d152cf5dSBjorn Helgaas int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
2721da177e4SLinus Torvalds {
273c4da6940SBjorn Helgaas 	struct acpi_device *acpi_dev = dev->data;
274c4da6940SBjorn Helgaas 	acpi_handle handle = acpi_dev->handle;
275d152cf5dSBjorn Helgaas 	acpi_status status;
2764ab55d8dSBjorn Helgaas 
2772f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "parse allocated resources\n");
27872dcc883SBjorn Helgaas 
279f4490002SBjorn Helgaas 	pnp_init_resources(dev);
2801da177e4SLinus Torvalds 
281d152cf5dSBjorn Helgaas 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
2824ab55d8dSBjorn Helgaas 				     pnpacpi_allocated_resource, dev);
283d152cf5dSBjorn Helgaas 
284d152cf5dSBjorn Helgaas 	if (ACPI_FAILURE(status)) {
285d152cf5dSBjorn Helgaas 		if (status != AE_NOT_FOUND)
286d152cf5dSBjorn Helgaas 			dev_err(&dev->dev, "can't evaluate _CRS: %d", status);
287d152cf5dSBjorn Helgaas 		return -EPERM;
288d152cf5dSBjorn Helgaas 	}
289d152cf5dSBjorn Helgaas 	return 0;
2901da177e4SLinus Torvalds }
2911da177e4SLinus Torvalds 
pnpacpi_parse_dma_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource_dma * p)292c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
2931f32ca31SBjorn Helgaas 					    unsigned int option_flags,
2949dd78466SBjorn Helgaas 					    struct acpi_resource_dma *p)
2951da177e4SLinus Torvalds {
2961da177e4SLinus Torvalds 	int i;
29718fd470aSWitold Szczeponik 	unsigned char map = 0, flags;
2981da177e4SLinus Torvalds 
29950eca3ebSBob Moore 	for (i = 0; i < p->channel_count; i++)
300c227536bSBjorn Helgaas 		map |= 1 << p->channels[i];
301362ea087SMichael Karcher 
30218fd470aSWitold Szczeponik 	flags = dma_flags(dev, p->type, p->bus_master, p->transfer);
3031f32ca31SBjorn Helgaas 	pnp_register_dma_resource(dev, option_flags, map, flags);
3041da177e4SLinus Torvalds }
3051da177e4SLinus Torvalds 
pnpacpi_parse_irq_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource_irq * p)306c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
3071f32ca31SBjorn Helgaas 					    unsigned int option_flags,
3081da177e4SLinus Torvalds 					    struct acpi_resource_irq *p)
3091da177e4SLinus Torvalds {
3101da177e4SLinus Torvalds 	int i;
311c227536bSBjorn Helgaas 	pnp_irq_mask_t map;
31218fd470aSWitold Szczeponik 	unsigned char flags;
3131da177e4SLinus Torvalds 
314c227536bSBjorn Helgaas 	bitmap_zero(map.bits, PNP_IRQ_NR);
31550eca3ebSBob Moore 	for (i = 0; i < p->interrupt_count; i++)
3161da177e4SLinus Torvalds 		if (p->interrupts[i])
317c227536bSBjorn Helgaas 			__set_bit(p->interrupts[i], map.bits);
3181da177e4SLinus Torvalds 
3195ff81160SRaul E Rangel 	flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->shareable, p->wake_capable);
3201f32ca31SBjorn Helgaas 	pnp_register_irq_resource(dev, option_flags, &map, flags);
3211da177e4SLinus Torvalds }
3221da177e4SLinus Torvalds 
pnpacpi_parse_ext_irq_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource_extended_irq * p)323c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
3241f32ca31SBjorn Helgaas 					unsigned int option_flags,
32550eca3ebSBob Moore 					struct acpi_resource_extended_irq *p)
3261da177e4SLinus Torvalds {
3271da177e4SLinus Torvalds 	int i;
328c227536bSBjorn Helgaas 	pnp_irq_mask_t map;
32918fd470aSWitold Szczeponik 	unsigned char flags;
3301da177e4SLinus Torvalds 
331c227536bSBjorn Helgaas 	bitmap_zero(map.bits, PNP_IRQ_NR);
332fe2cf598SBjorn Helgaas 	for (i = 0; i < p->interrupt_count; i++) {
333fe2cf598SBjorn Helgaas 		if (p->interrupts[i]) {
334fe2cf598SBjorn Helgaas 			if (p->interrupts[i] < PNP_IRQ_NR)
335c227536bSBjorn Helgaas 				__set_bit(p->interrupts[i], map.bits);
336fe2cf598SBjorn Helgaas 			else
3371d7f2cddSAndy Shevchenko 				dev_err(&dev->dev,
3381d7f2cddSAndy Shevchenko 					"ignoring IRQ %d option (too large for %d entry bitmap)\n",
339fe2cf598SBjorn Helgaas 					p->interrupts[i], PNP_IRQ_NR);
340fe2cf598SBjorn Helgaas 		}
341fe2cf598SBjorn Helgaas 	}
3421da177e4SLinus Torvalds 
3435ff81160SRaul E Rangel 	flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->shareable, p->wake_capable);
3441f32ca31SBjorn Helgaas 	pnp_register_irq_resource(dev, option_flags, &map, flags);
3451da177e4SLinus Torvalds }
3461da177e4SLinus Torvalds 
pnpacpi_parse_port_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource_io * io)347c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
3481f32ca31SBjorn Helgaas 					     unsigned int option_flags,
3491da177e4SLinus Torvalds 					     struct acpi_resource_io *io)
3501da177e4SLinus Torvalds {
351c227536bSBjorn Helgaas 	unsigned char flags = 0;
3521da177e4SLinus Torvalds 
353c227536bSBjorn Helgaas 	if (io->io_decode == ACPI_DECODE_16)
35418fd470aSWitold Szczeponik 		flags = IORESOURCE_IO_16BIT_ADDR;
3551f32ca31SBjorn Helgaas 	pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
356c227536bSBjorn Helgaas 				   io->alignment, io->address_length, flags);
3571da177e4SLinus Torvalds }
3581da177e4SLinus Torvalds 
pnpacpi_parse_fixed_port_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource_fixed_io * io)359c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
3601f32ca31SBjorn Helgaas 					unsigned int option_flags,
3611da177e4SLinus Torvalds 					struct acpi_resource_fixed_io *io)
3621da177e4SLinus Torvalds {
3631f32ca31SBjorn Helgaas 	pnp_register_port_resource(dev, option_flags, io->address, io->address,
36418fd470aSWitold Szczeponik 				   0, io->address_length, IORESOURCE_IO_FIXED);
3651da177e4SLinus Torvalds }
3661da177e4SLinus Torvalds 
pnpacpi_parse_mem24_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource_memory24 * p)367c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
3681f32ca31SBjorn Helgaas 					      unsigned int option_flags,
36950eca3ebSBob Moore 					      struct acpi_resource_memory24 *p)
3701da177e4SLinus Torvalds {
371c227536bSBjorn Helgaas 	unsigned char flags = 0;
3721da177e4SLinus Torvalds 
373c227536bSBjorn Helgaas 	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
37418fd470aSWitold Szczeponik 		flags = IORESOURCE_MEM_WRITEABLE;
3751f32ca31SBjorn Helgaas 	pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
376c227536bSBjorn Helgaas 				  p->alignment, p->address_length, flags);
3771da177e4SLinus Torvalds }
3781da177e4SLinus Torvalds 
pnpacpi_parse_mem32_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource_memory32 * p)379c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
3801f32ca31SBjorn Helgaas 					      unsigned int option_flags,
38150eca3ebSBob Moore 					      struct acpi_resource_memory32 *p)
3821da177e4SLinus Torvalds {
383c227536bSBjorn Helgaas 	unsigned char flags = 0;
3841da177e4SLinus Torvalds 
385c227536bSBjorn Helgaas 	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
38618fd470aSWitold Szczeponik 		flags = IORESOURCE_MEM_WRITEABLE;
3871f32ca31SBjorn Helgaas 	pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
388c227536bSBjorn Helgaas 				  p->alignment, p->address_length, flags);
3891da177e4SLinus Torvalds }
3901da177e4SLinus Torvalds 
pnpacpi_parse_fixed_mem32_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource_fixed_memory32 * p)391c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
3921f32ca31SBjorn Helgaas 					unsigned int option_flags,
39350eca3ebSBob Moore 					struct acpi_resource_fixed_memory32 *p)
3941da177e4SLinus Torvalds {
395c227536bSBjorn Helgaas 	unsigned char flags = 0;
3961da177e4SLinus Torvalds 
397c227536bSBjorn Helgaas 	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
39818fd470aSWitold Szczeponik 		flags = IORESOURCE_MEM_WRITEABLE;
3991f32ca31SBjorn Helgaas 	pnp_register_mem_resource(dev, option_flags, p->address, p->address,
400c227536bSBjorn Helgaas 				  0, p->address_length, flags);
4011da177e4SLinus Torvalds }
4021da177e4SLinus Torvalds 
pnpacpi_parse_address_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource * r)403c1caf06cSBjorn Helgaas static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
4041f32ca31SBjorn Helgaas 						unsigned int option_flags,
40507d4e9afSBjorn Helgaas 						struct acpi_resource *r)
4066f957eafSBjorn Helgaas {
4076f957eafSBjorn Helgaas 	struct acpi_resource_address64 addr, *p = &addr;
4086f957eafSBjorn Helgaas 	acpi_status status;
409c227536bSBjorn Helgaas 	unsigned char flags = 0;
4106f957eafSBjorn Helgaas 
4116f957eafSBjorn Helgaas 	status = acpi_resource_to_address64(r, p);
412958a1fddSBjorn Helgaas 	if (ACPI_FAILURE(status)) {
413958a1fddSBjorn Helgaas 		dev_warn(&dev->dev, "can't convert resource type %d\n",
4149dd78466SBjorn Helgaas 			 r->type);
4156f957eafSBjorn Helgaas 		return;
4166f957eafSBjorn Helgaas 	}
4176f957eafSBjorn Helgaas 
4186f957eafSBjorn Helgaas 	if (p->resource_type == ACPI_MEMORY_RANGE) {
419c227536bSBjorn Helgaas 		if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
42018fd470aSWitold Szczeponik 			flags = IORESOURCE_MEM_WRITEABLE;
421a45de93eSLv Zheng 		pnp_register_mem_resource(dev, option_flags, p->address.minimum,
422a45de93eSLv Zheng 					  p->address.minimum, 0, p->address.address_length,
4231f32ca31SBjorn Helgaas 					  flags);
424c227536bSBjorn Helgaas 	} else if (p->resource_type == ACPI_IO_RANGE)
425a45de93eSLv Zheng 		pnp_register_port_resource(dev, option_flags, p->address.minimum,
426a45de93eSLv Zheng 					   p->address.minimum, 0, p->address.address_length,
42718fd470aSWitold Szczeponik 					   IORESOURCE_IO_FIXED);
4286f957eafSBjorn Helgaas }
4296f957eafSBjorn Helgaas 
pnpacpi_parse_ext_address_option(struct pnp_dev * dev,unsigned int option_flags,struct acpi_resource * r)4308cb24c8fSBjorn Helgaas static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev,
4318cb24c8fSBjorn Helgaas 						    unsigned int option_flags,
4328cb24c8fSBjorn Helgaas 						    struct acpi_resource *r)
4338cb24c8fSBjorn Helgaas {
4348cb24c8fSBjorn Helgaas 	struct acpi_resource_extended_address64 *p = &r->data.ext_address64;
4358cb24c8fSBjorn Helgaas 	unsigned char flags = 0;
4368cb24c8fSBjorn Helgaas 
4378cb24c8fSBjorn Helgaas 	if (p->resource_type == ACPI_MEMORY_RANGE) {
4388cb24c8fSBjorn Helgaas 		if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
43918fd470aSWitold Szczeponik 			flags = IORESOURCE_MEM_WRITEABLE;
440a45de93eSLv Zheng 		pnp_register_mem_resource(dev, option_flags, p->address.minimum,
441a45de93eSLv Zheng 					  p->address.minimum, 0, p->address.address_length,
4428cb24c8fSBjorn Helgaas 					  flags);
4438cb24c8fSBjorn Helgaas 	} else if (p->resource_type == ACPI_IO_RANGE)
444a45de93eSLv Zheng 		pnp_register_port_resource(dev, option_flags, p->address.minimum,
445a45de93eSLv Zheng 					   p->address.minimum, 0, p->address.address_length,
44618fd470aSWitold Szczeponik 					   IORESOURCE_IO_FIXED);
4478cb24c8fSBjorn Helgaas }
4488cb24c8fSBjorn Helgaas 
4491da177e4SLinus Torvalds struct acpipnp_parse_option_s {
4501da177e4SLinus Torvalds 	struct pnp_dev *dev;
4511f32ca31SBjorn Helgaas 	unsigned int option_flags;
4521da177e4SLinus Torvalds };
4531da177e4SLinus Torvalds 
pnpacpi_option_resource(struct acpi_resource * res,void * data)4542bb9a6b3SThomas Renninger static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
4551da177e4SLinus Torvalds 						  void *data)
4561da177e4SLinus Torvalds {
457e2a1a6f1SBjorn Helgaas 	int priority;
4584721a4ccSBjorn Helgaas 	struct acpipnp_parse_option_s *parse_data = data;
4591da177e4SLinus Torvalds 	struct pnp_dev *dev = parse_data->dev;
4601f32ca31SBjorn Helgaas 	unsigned int option_flags = parse_data->option_flags;
4611da177e4SLinus Torvalds 
462eca008c8SLen Brown 	switch (res->type) {
46350eca3ebSBob Moore 	case ACPI_RESOURCE_TYPE_IRQ:
4641f32ca31SBjorn Helgaas 		pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq);
4651da177e4SLinus Torvalds 		break;
4660af5853bSLen Brown 
46750eca3ebSBob Moore 	case ACPI_RESOURCE_TYPE_DMA:
4681f32ca31SBjorn Helgaas 		pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma);
4691da177e4SLinus Torvalds 		break;
4700af5853bSLen Brown 
47150eca3ebSBob Moore 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
4721da177e4SLinus Torvalds 		switch (res->data.start_dpf.compatibility_priority) {
4731da177e4SLinus Torvalds 		case ACPI_GOOD_CONFIGURATION:
4741da177e4SLinus Torvalds 			priority = PNP_RES_PRIORITY_PREFERRED;
4751da177e4SLinus Torvalds 			break;
4761da177e4SLinus Torvalds 
4771da177e4SLinus Torvalds 		case ACPI_ACCEPTABLE_CONFIGURATION:
4781da177e4SLinus Torvalds 			priority = PNP_RES_PRIORITY_ACCEPTABLE;
4791da177e4SLinus Torvalds 			break;
4801da177e4SLinus Torvalds 
4811da177e4SLinus Torvalds 		case ACPI_SUB_OPTIMAL_CONFIGURATION:
4821da177e4SLinus Torvalds 			priority = PNP_RES_PRIORITY_FUNCTIONAL;
4831da177e4SLinus Torvalds 			break;
4841da177e4SLinus Torvalds 		default:
4851da177e4SLinus Torvalds 			priority = PNP_RES_PRIORITY_INVALID;
4861da177e4SLinus Torvalds 			break;
4871da177e4SLinus Torvalds 		}
4881f32ca31SBjorn Helgaas 		parse_data->option_flags = pnp_new_dependent_set(dev, priority);
4891da177e4SLinus Torvalds 		break;
4900af5853bSLen Brown 
49150eca3ebSBob Moore 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
4921f32ca31SBjorn Helgaas 		parse_data->option_flags = 0;
493b008b8d7SMatthieu Castet 		break;
4940af5853bSLen Brown 
4950af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_IO:
4961f32ca31SBjorn Helgaas 		pnpacpi_parse_port_option(dev, option_flags, &res->data.io);
4970af5853bSLen Brown 		break;
4980af5853bSLen Brown 
4990af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_FIXED_IO:
5001f32ca31SBjorn Helgaas 		pnpacpi_parse_fixed_port_option(dev, option_flags,
501c1caf06cSBjorn Helgaas 					        &res->data.fixed_io);
5020af5853bSLen Brown 		break;
5030af5853bSLen Brown 
5040af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_VENDOR:
5050af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_END_TAG:
5060af5853bSLen Brown 		break;
5070af5853bSLen Brown 
5080af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_MEMORY24:
5091f32ca31SBjorn Helgaas 		pnpacpi_parse_mem24_option(dev, option_flags,
5101f32ca31SBjorn Helgaas 					   &res->data.memory24);
5110af5853bSLen Brown 		break;
5120af5853bSLen Brown 
5130af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_MEMORY32:
5141f32ca31SBjorn Helgaas 		pnpacpi_parse_mem32_option(dev, option_flags,
5151f32ca31SBjorn Helgaas 					   &res->data.memory32);
5160af5853bSLen Brown 		break;
5170af5853bSLen Brown 
5180af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
5191f32ca31SBjorn Helgaas 		pnpacpi_parse_fixed_mem32_option(dev, option_flags,
5200af5853bSLen Brown 						 &res->data.fixed_memory32);
5210af5853bSLen Brown 		break;
5220af5853bSLen Brown 
5230af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_ADDRESS16:
5240af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_ADDRESS32:
5250af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_ADDRESS64:
5261f32ca31SBjorn Helgaas 		pnpacpi_parse_address_option(dev, option_flags, res);
5270af5853bSLen Brown 		break;
5280af5853bSLen Brown 
5290af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
5308cb24c8fSBjorn Helgaas 		pnpacpi_parse_ext_address_option(dev, option_flags, res);
5310af5853bSLen Brown 		break;
5320af5853bSLen Brown 
5330af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
5341f32ca31SBjorn Helgaas 		pnpacpi_parse_ext_irq_option(dev, option_flags,
535c1caf06cSBjorn Helgaas 					     &res->data.extended_irq);
5360af5853bSLen Brown 		break;
5370af5853bSLen Brown 
5380af5853bSLen Brown 	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
5390af5853bSLen Brown 		break;
5400af5853bSLen Brown 
5411da177e4SLinus Torvalds 	default:
542af11cb2dSBjorn Helgaas 		dev_warn(&dev->dev, "unknown resource type %d in _PRS\n",
543af11cb2dSBjorn Helgaas 			 res->type);
5441da177e4SLinus Torvalds 		return AE_ERROR;
5451da177e4SLinus Torvalds 	}
5461da177e4SLinus Torvalds 
5471da177e4SLinus Torvalds 	return AE_OK;
5481da177e4SLinus Torvalds }
5491da177e4SLinus Torvalds 
pnpacpi_parse_resource_option_data(struct pnp_dev * dev)550d152cf5dSBjorn Helgaas int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
5511da177e4SLinus Torvalds {
552c4da6940SBjorn Helgaas 	struct acpi_device *acpi_dev = dev->data;
553c4da6940SBjorn Helgaas 	acpi_handle handle = acpi_dev->handle;
5541da177e4SLinus Torvalds 	acpi_status status;
5551da177e4SLinus Torvalds 	struct acpipnp_parse_option_s parse_data;
5561da177e4SLinus Torvalds 
5572f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "parse resource options\n");
55872dcc883SBjorn Helgaas 
5591da177e4SLinus Torvalds 	parse_data.dev = dev;
5601f32ca31SBjorn Helgaas 	parse_data.option_flags = 0;
5611f32ca31SBjorn Helgaas 
5621da177e4SLinus Torvalds 	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
5631da177e4SLinus Torvalds 				     pnpacpi_option_resource, &parse_data);
5641da177e4SLinus Torvalds 
565d152cf5dSBjorn Helgaas 	if (ACPI_FAILURE(status)) {
566d152cf5dSBjorn Helgaas 		if (status != AE_NOT_FOUND)
567d152cf5dSBjorn Helgaas 			dev_err(&dev->dev, "can't evaluate _PRS: %d", status);
568d152cf5dSBjorn Helgaas 		return -EPERM;
569d152cf5dSBjorn Helgaas 	}
570d152cf5dSBjorn Helgaas 	return 0;
5711da177e4SLinus Torvalds }
5721da177e4SLinus Torvalds 
pnpacpi_supported_resource(struct acpi_resource * res)573b5f2490bSBjorn Helgaas static int pnpacpi_supported_resource(struct acpi_resource *res)
574b5f2490bSBjorn Helgaas {
575b5f2490bSBjorn Helgaas 	switch (res->type) {
576b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_IRQ:
577b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_DMA:
578b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_IO:
579b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_FIXED_IO:
580b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_MEMORY24:
581b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_MEMORY32:
582b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
583b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_ADDRESS16:
584b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_ADDRESS32:
585b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_ADDRESS64:
5868cb24c8fSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
587b5f2490bSBjorn Helgaas 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
588b5f2490bSBjorn Helgaas 		return 1;
589b5f2490bSBjorn Helgaas 	}
590b5f2490bSBjorn Helgaas 	return 0;
591b5f2490bSBjorn Helgaas }
592b5f2490bSBjorn Helgaas 
5931da177e4SLinus Torvalds /*
5941da177e4SLinus Torvalds  * Set resource
5951da177e4SLinus Torvalds  */
pnpacpi_count_resources(struct acpi_resource * res,void * data)5961da177e4SLinus Torvalds static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
5971da177e4SLinus Torvalds 					   void *data)
5981da177e4SLinus Torvalds {
5994721a4ccSBjorn Helgaas 	int *res_cnt = data;
600b5f2490bSBjorn Helgaas 
601b5f2490bSBjorn Helgaas 	if (pnpacpi_supported_resource(res))
6021da177e4SLinus Torvalds 		(*res_cnt)++;
6031da177e4SLinus Torvalds 	return AE_OK;
6041da177e4SLinus Torvalds }
6051da177e4SLinus Torvalds 
pnpacpi_type_resources(struct acpi_resource * res,void * data)6061c6e7d0aSBjorn Helgaas static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
6071da177e4SLinus Torvalds {
6084721a4ccSBjorn Helgaas 	struct acpi_resource **resource = data;
609b5f2490bSBjorn Helgaas 
610b5f2490bSBjorn Helgaas 	if (pnpacpi_supported_resource(res)) {
611eca008c8SLen Brown 		(*resource)->type = res->type;
612b5f2490bSBjorn Helgaas 		(*resource)->length = sizeof(struct acpi_resource);
61336d872a3SBjorn Helgaas 		if (res->type == ACPI_RESOURCE_TYPE_IRQ)
61436d872a3SBjorn Helgaas 			(*resource)->data.irq.descriptor_length =
61536d872a3SBjorn Helgaas 					res->data.irq.descriptor_length;
6161da177e4SLinus Torvalds 		(*resource)++;
6171da177e4SLinus Torvalds 	}
6181da177e4SLinus Torvalds 
6191da177e4SLinus Torvalds 	return AE_OK;
6201da177e4SLinus Torvalds }
6211da177e4SLinus Torvalds 
pnpacpi_build_resource_template(struct pnp_dev * dev,struct acpi_buffer * buffer)622cdef6254SBjorn Helgaas int pnpacpi_build_resource_template(struct pnp_dev *dev,
6231da177e4SLinus Torvalds 				    struct acpi_buffer *buffer)
6241da177e4SLinus Torvalds {
625c4da6940SBjorn Helgaas 	struct acpi_device *acpi_dev = dev->data;
626c4da6940SBjorn Helgaas 	acpi_handle handle = acpi_dev->handle;
6271da177e4SLinus Torvalds 	struct acpi_resource *resource;
6281da177e4SLinus Torvalds 	int res_cnt = 0;
6291da177e4SLinus Torvalds 	acpi_status status;
6301da177e4SLinus Torvalds 
6311da177e4SLinus Torvalds 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
6321da177e4SLinus Torvalds 				     pnpacpi_count_resources, &res_cnt);
6331da177e4SLinus Torvalds 	if (ACPI_FAILURE(status)) {
634d152cf5dSBjorn Helgaas 		dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
6351da177e4SLinus Torvalds 		return -EINVAL;
6361da177e4SLinus Torvalds 	}
6371da177e4SLinus Torvalds 	if (!res_cnt)
6381da177e4SLinus Torvalds 		return -EINVAL;
6391da177e4SLinus Torvalds 	buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
640cd861280SRobert P. J. Day 	buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
6411da177e4SLinus Torvalds 	if (!buffer->pointer)
6421da177e4SLinus Torvalds 		return -ENOMEM;
64372dcc883SBjorn Helgaas 
6441da177e4SLinus Torvalds 	resource = (struct acpi_resource *)buffer->pointer;
6451da177e4SLinus Torvalds 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
6461da177e4SLinus Torvalds 				     pnpacpi_type_resources, &resource);
6471da177e4SLinus Torvalds 	if (ACPI_FAILURE(status)) {
6481da177e4SLinus Torvalds 		kfree(buffer->pointer);
649d152cf5dSBjorn Helgaas 		dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
6501da177e4SLinus Torvalds 		return -EINVAL;
6511da177e4SLinus Torvalds 	}
6521da177e4SLinus Torvalds 	/* resource will pointer the end resource now */
65350eca3ebSBob Moore 	resource->type = ACPI_RESOURCE_TYPE_END_TAG;
654f084dbb9SYinghai Lu 	resource->length = sizeof(struct acpi_resource);
6551da177e4SLinus Torvalds 
6561da177e4SLinus Torvalds 	return 0;
6571da177e4SLinus Torvalds }
6581da177e4SLinus Torvalds 
pnpacpi_encode_irq(struct pnp_dev * dev,struct acpi_resource * resource,struct resource * p)65972dcc883SBjorn Helgaas static void pnpacpi_encode_irq(struct pnp_dev *dev,
66072dcc883SBjorn Helgaas 			       struct acpi_resource *resource,
6611da177e4SLinus Torvalds 			       struct resource *p)
6621da177e4SLinus Torvalds {
6639570a20eSBjorn Helgaas 	struct acpi_resource_irq *irq = &resource->data.irq;
664bbee06d0SFabian Frederick 	u8 triggering, polarity, shareable;
6651da177e4SLinus Torvalds 
666aee3ad81SBjorn Helgaas 	if (!pnp_resource_enabled(p)) {
667aee3ad81SBjorn Helgaas 		irq->interrupt_count = 0;
6682f53432cSBjorn Helgaas 		pnp_dbg(&dev->dev, "  encode irq (%s)\n",
669aee3ad81SBjorn Helgaas 			p ? "disabled" : "missing");
670aee3ad81SBjorn Helgaas 		return;
671aee3ad81SBjorn Helgaas 	}
672aee3ad81SBjorn Helgaas 
673a993273bSBjorn Helgaas 	decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
6749570a20eSBjorn Helgaas 	irq->triggering = triggering;
6759570a20eSBjorn Helgaas 	irq->polarity = polarity;
676c163f90cSErik Schmauss 	irq->shareable = shareable;
6779570a20eSBjorn Helgaas 	irq->interrupt_count = 1;
6789570a20eSBjorn Helgaas 	irq->interrupts[0] = p->start;
67972dcc883SBjorn Helgaas 
6802f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
68136d872a3SBjorn Helgaas 		(int) p->start,
68272dcc883SBjorn Helgaas 		triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
68372dcc883SBjorn Helgaas 		polarity == ACPI_ACTIVE_LOW ? "low" : "high",
684c163f90cSErik Schmauss 		irq->shareable == ACPI_SHARED ? "shared" : "exclusive",
68536d872a3SBjorn Helgaas 		irq->descriptor_length);
6861da177e4SLinus Torvalds }
6871da177e4SLinus Torvalds 
pnpacpi_encode_ext_irq(struct pnp_dev * dev,struct acpi_resource * resource,struct resource * p)68872dcc883SBjorn Helgaas static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
68972dcc883SBjorn Helgaas 				   struct acpi_resource *resource,
6901da177e4SLinus Torvalds 				   struct resource *p)
6911da177e4SLinus Torvalds {
6929570a20eSBjorn Helgaas 	struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
693bbee06d0SFabian Frederick 	u8 triggering, polarity, shareable;
6941da177e4SLinus Torvalds 
695aee3ad81SBjorn Helgaas 	if (!pnp_resource_enabled(p)) {
696aee3ad81SBjorn Helgaas 		extended_irq->interrupt_count = 0;
6972f53432cSBjorn Helgaas 		pnp_dbg(&dev->dev, "  encode extended irq (%s)\n",
698aee3ad81SBjorn Helgaas 			p ? "disabled" : "missing");
699aee3ad81SBjorn Helgaas 		return;
700aee3ad81SBjorn Helgaas 	}
701aee3ad81SBjorn Helgaas 
702a993273bSBjorn Helgaas 	decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
7039570a20eSBjorn Helgaas 	extended_irq->producer_consumer = ACPI_CONSUMER;
7049570a20eSBjorn Helgaas 	extended_irq->triggering = triggering;
7059570a20eSBjorn Helgaas 	extended_irq->polarity = polarity;
706c163f90cSErik Schmauss 	extended_irq->shareable = shareable;
7079570a20eSBjorn Helgaas 	extended_irq->interrupt_count = 1;
7089570a20eSBjorn Helgaas 	extended_irq->interrupts[0] = p->start;
70972dcc883SBjorn Helgaas 
7102f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "  encode irq %d %s %s %s\n", (int) p->start,
71172dcc883SBjorn Helgaas 		triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
71272dcc883SBjorn Helgaas 		polarity == ACPI_ACTIVE_LOW ? "low" : "high",
713c163f90cSErik Schmauss 		extended_irq->shareable == ACPI_SHARED ? "shared" : "exclusive");
7141da177e4SLinus Torvalds }
7151da177e4SLinus Torvalds 
pnpacpi_encode_dma(struct pnp_dev * dev,struct acpi_resource * resource,struct resource * p)71672dcc883SBjorn Helgaas static void pnpacpi_encode_dma(struct pnp_dev *dev,
71772dcc883SBjorn Helgaas 			       struct acpi_resource *resource,
7181da177e4SLinus Torvalds 			       struct resource *p)
7191da177e4SLinus Torvalds {
7209570a20eSBjorn Helgaas 	struct acpi_resource_dma *dma = &resource->data.dma;
7219570a20eSBjorn Helgaas 
722aee3ad81SBjorn Helgaas 	if (!pnp_resource_enabled(p)) {
723aee3ad81SBjorn Helgaas 		dma->channel_count = 0;
7242f53432cSBjorn Helgaas 		pnp_dbg(&dev->dev, "  encode dma (%s)\n",
725aee3ad81SBjorn Helgaas 			p ? "disabled" : "missing");
726aee3ad81SBjorn Helgaas 		return;
727aee3ad81SBjorn Helgaas 	}
728aee3ad81SBjorn Helgaas 
7291da177e4SLinus Torvalds 	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
730ccc4c7bbSVojtech Pavlik 	switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
731ccc4c7bbSVojtech Pavlik 	case IORESOURCE_DMA_TYPEA:
7329570a20eSBjorn Helgaas 		dma->type = ACPI_TYPE_A;
733ccc4c7bbSVojtech Pavlik 		break;
734ccc4c7bbSVojtech Pavlik 	case IORESOURCE_DMA_TYPEB:
7359570a20eSBjorn Helgaas 		dma->type = ACPI_TYPE_B;
736ccc4c7bbSVojtech Pavlik 		break;
737ccc4c7bbSVojtech Pavlik 	case IORESOURCE_DMA_TYPEF:
7389570a20eSBjorn Helgaas 		dma->type = ACPI_TYPE_F;
739ccc4c7bbSVojtech Pavlik 		break;
740ccc4c7bbSVojtech Pavlik 	default:
7419570a20eSBjorn Helgaas 		dma->type = ACPI_COMPATIBILITY;
742ccc4c7bbSVojtech Pavlik 	}
743ccc4c7bbSVojtech Pavlik 
744ccc4c7bbSVojtech Pavlik 	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
745ccc4c7bbSVojtech Pavlik 	case IORESOURCE_DMA_8BIT:
7469570a20eSBjorn Helgaas 		dma->transfer = ACPI_TRANSFER_8;
747ccc4c7bbSVojtech Pavlik 		break;
748ccc4c7bbSVojtech Pavlik 	case IORESOURCE_DMA_8AND16BIT:
7499570a20eSBjorn Helgaas 		dma->transfer = ACPI_TRANSFER_8_16;
750ccc4c7bbSVojtech Pavlik 		break;
751ccc4c7bbSVojtech Pavlik 	default:
7529570a20eSBjorn Helgaas 		dma->transfer = ACPI_TRANSFER_16;
753ccc4c7bbSVojtech Pavlik 	}
754ccc4c7bbSVojtech Pavlik 
7559570a20eSBjorn Helgaas 	dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
7569570a20eSBjorn Helgaas 	dma->channel_count = 1;
7579570a20eSBjorn Helgaas 	dma->channels[0] = p->start;
75872dcc883SBjorn Helgaas 
7592f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "  encode dma %d "
76072dcc883SBjorn Helgaas 		"type %#x transfer %#x master %d\n",
76172dcc883SBjorn Helgaas 		(int) p->start, dma->type, dma->transfer, dma->bus_master);
7621da177e4SLinus Torvalds }
7631da177e4SLinus Torvalds 
pnpacpi_encode_io(struct pnp_dev * dev,struct acpi_resource * resource,struct resource * p)76472dcc883SBjorn Helgaas static void pnpacpi_encode_io(struct pnp_dev *dev,
76572dcc883SBjorn Helgaas 			      struct acpi_resource *resource,
7661da177e4SLinus Torvalds 			      struct resource *p)
7671da177e4SLinus Torvalds {
7689570a20eSBjorn Helgaas 	struct acpi_resource_io *io = &resource->data.io;
7699570a20eSBjorn Helgaas 
770aee3ad81SBjorn Helgaas 	if (pnp_resource_enabled(p)) {
771aee3ad81SBjorn Helgaas 		/* Note: pnp_assign_port copies pnp_port->flags into p->flags */
77208c9f262SBjorn Helgaas 		io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
7731da177e4SLinus Torvalds 		    ACPI_DECODE_16 : ACPI_DECODE_10;
7749570a20eSBjorn Helgaas 		io->minimum = p->start;
7759570a20eSBjorn Helgaas 		io->maximum = p->end;
7769570a20eSBjorn Helgaas 		io->alignment = 0;	/* Correct? */
77728f65c11SJoe Perches 		io->address_length = resource_size(p);
778aee3ad81SBjorn Helgaas 	} else {
779aee3ad81SBjorn Helgaas 		io->minimum = 0;
780aee3ad81SBjorn Helgaas 		io->address_length = 0;
781aee3ad81SBjorn Helgaas 	}
78272dcc883SBjorn Helgaas 
7832f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "  encode io %#x-%#x decode %#x\n", io->minimum,
784aee3ad81SBjorn Helgaas 		io->minimum + io->address_length - 1, io->io_decode);
7851da177e4SLinus Torvalds }
7861da177e4SLinus Torvalds 
pnpacpi_encode_fixed_io(struct pnp_dev * dev,struct acpi_resource * resource,struct resource * p)78772dcc883SBjorn Helgaas static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
78872dcc883SBjorn Helgaas 				    struct acpi_resource *resource,
7891da177e4SLinus Torvalds 				    struct resource *p)
7901da177e4SLinus Torvalds {
7919570a20eSBjorn Helgaas 	struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
7929570a20eSBjorn Helgaas 
793aee3ad81SBjorn Helgaas 	if (pnp_resource_enabled(p)) {
7949570a20eSBjorn Helgaas 		fixed_io->address = p->start;
79528f65c11SJoe Perches 		fixed_io->address_length = resource_size(p);
796aee3ad81SBjorn Helgaas 	} else {
797aee3ad81SBjorn Helgaas 		fixed_io->address = 0;
798aee3ad81SBjorn Helgaas 		fixed_io->address_length = 0;
799aee3ad81SBjorn Helgaas 	}
80072dcc883SBjorn Helgaas 
8012f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
802aee3ad81SBjorn Helgaas 		fixed_io->address + fixed_io->address_length - 1);
8031da177e4SLinus Torvalds }
8041da177e4SLinus Torvalds 
pnpacpi_encode_mem24(struct pnp_dev * dev,struct acpi_resource * resource,struct resource * p)80572dcc883SBjorn Helgaas static void pnpacpi_encode_mem24(struct pnp_dev *dev,
80672dcc883SBjorn Helgaas 				 struct acpi_resource *resource,
8071da177e4SLinus Torvalds 				 struct resource *p)
8081da177e4SLinus Torvalds {
8099570a20eSBjorn Helgaas 	struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
8109570a20eSBjorn Helgaas 
811aee3ad81SBjorn Helgaas 	if (pnp_resource_enabled(p)) {
812aee3ad81SBjorn Helgaas 		/* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
813aee3ad81SBjorn Helgaas 		memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
8141da177e4SLinus Torvalds 		    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
8159570a20eSBjorn Helgaas 		memory24->minimum = p->start;
8169570a20eSBjorn Helgaas 		memory24->maximum = p->end;
8179570a20eSBjorn Helgaas 		memory24->alignment = 0;
81828f65c11SJoe Perches 		memory24->address_length = resource_size(p);
819aee3ad81SBjorn Helgaas 	} else {
820aee3ad81SBjorn Helgaas 		memory24->minimum = 0;
821aee3ad81SBjorn Helgaas 		memory24->address_length = 0;
822aee3ad81SBjorn Helgaas 	}
82372dcc883SBjorn Helgaas 
8242f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "  encode mem24 %#x-%#x write_protect %#x\n",
825aee3ad81SBjorn Helgaas 		memory24->minimum,
826aee3ad81SBjorn Helgaas 		memory24->minimum + memory24->address_length - 1,
82772dcc883SBjorn Helgaas 		memory24->write_protect);
8281da177e4SLinus Torvalds }
8291da177e4SLinus Torvalds 
pnpacpi_encode_mem32(struct pnp_dev * dev,struct acpi_resource * resource,struct resource * p)83072dcc883SBjorn Helgaas static void pnpacpi_encode_mem32(struct pnp_dev *dev,
83172dcc883SBjorn Helgaas 				 struct acpi_resource *resource,
8321da177e4SLinus Torvalds 				 struct resource *p)
8331da177e4SLinus Torvalds {
8349570a20eSBjorn Helgaas 	struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
8359570a20eSBjorn Helgaas 
836aee3ad81SBjorn Helgaas 	if (pnp_resource_enabled(p)) {
837aee3ad81SBjorn Helgaas 		memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
8381da177e4SLinus Torvalds 		    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
8399570a20eSBjorn Helgaas 		memory32->minimum = p->start;
8409570a20eSBjorn Helgaas 		memory32->maximum = p->end;
8419570a20eSBjorn Helgaas 		memory32->alignment = 0;
84228f65c11SJoe Perches 		memory32->address_length = resource_size(p);
843aee3ad81SBjorn Helgaas 	} else {
844aee3ad81SBjorn Helgaas 		memory32->minimum = 0;
845aee3ad81SBjorn Helgaas 		memory32->alignment = 0;
846aee3ad81SBjorn Helgaas 	}
84772dcc883SBjorn Helgaas 
8482f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
849aee3ad81SBjorn Helgaas 		memory32->minimum,
850aee3ad81SBjorn Helgaas 		memory32->minimum + memory32->address_length - 1,
85172dcc883SBjorn Helgaas 		memory32->write_protect);
8521da177e4SLinus Torvalds }
8531da177e4SLinus Torvalds 
pnpacpi_encode_fixed_mem32(struct pnp_dev * dev,struct acpi_resource * resource,struct resource * p)85472dcc883SBjorn Helgaas static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
85572dcc883SBjorn Helgaas 				       struct acpi_resource *resource,
8561da177e4SLinus Torvalds 				       struct resource *p)
8571da177e4SLinus Torvalds {
8589570a20eSBjorn Helgaas 	struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
8599570a20eSBjorn Helgaas 
860aee3ad81SBjorn Helgaas 	if (pnp_resource_enabled(p)) {
8619570a20eSBjorn Helgaas 		fixed_memory32->write_protect =
862aee3ad81SBjorn Helgaas 		    p->flags & IORESOURCE_MEM_WRITEABLE ?
8631da177e4SLinus Torvalds 		    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
8649570a20eSBjorn Helgaas 		fixed_memory32->address = p->start;
86528f65c11SJoe Perches 		fixed_memory32->address_length = resource_size(p);
866aee3ad81SBjorn Helgaas 	} else {
867aee3ad81SBjorn Helgaas 		fixed_memory32->address = 0;
868aee3ad81SBjorn Helgaas 		fixed_memory32->address_length = 0;
869aee3ad81SBjorn Helgaas 	}
87072dcc883SBjorn Helgaas 
8712f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
872aee3ad81SBjorn Helgaas 		fixed_memory32->address,
873aee3ad81SBjorn Helgaas 		fixed_memory32->address + fixed_memory32->address_length - 1,
87472dcc883SBjorn Helgaas 		fixed_memory32->write_protect);
8751da177e4SLinus Torvalds }
8761da177e4SLinus Torvalds 
pnpacpi_encode_resources(struct pnp_dev * dev,struct acpi_buffer * buffer)8774ab55d8dSBjorn Helgaas int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
8781da177e4SLinus Torvalds {
8791da177e4SLinus Torvalds 	int i = 0;
8801da177e4SLinus Torvalds 	/* pnpacpi_build_resource_template allocates extra mem */
8811da177e4SLinus Torvalds 	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
8824721a4ccSBjorn Helgaas 	struct acpi_resource *resource = buffer->pointer;
883fac69a2bSFabian Frederick 	unsigned int port = 0, irq = 0, dma = 0, mem = 0;
8841da177e4SLinus Torvalds 
8852f53432cSBjorn Helgaas 	pnp_dbg(&dev->dev, "encode %d resources\n", res_cnt);
8861da177e4SLinus Torvalds 	while (i < res_cnt) {
887eca008c8SLen Brown 		switch (resource->type) {
88850eca3ebSBob Moore 		case ACPI_RESOURCE_TYPE_IRQ:
88972dcc883SBjorn Helgaas 			pnpacpi_encode_irq(dev, resource,
8907e2cf31fSBjorn Helgaas 			       pnp_get_resource(dev, IORESOURCE_IRQ, irq));
8911da177e4SLinus Torvalds 			irq++;
8921da177e4SLinus Torvalds 			break;
8931da177e4SLinus Torvalds 
89450eca3ebSBob Moore 		case ACPI_RESOURCE_TYPE_DMA:
89572dcc883SBjorn Helgaas 			pnpacpi_encode_dma(dev, resource,
8967e2cf31fSBjorn Helgaas 				pnp_get_resource(dev, IORESOURCE_DMA, dma));
8971da177e4SLinus Torvalds 			dma++;
8981da177e4SLinus Torvalds 			break;
89950eca3ebSBob Moore 		case ACPI_RESOURCE_TYPE_IO:
90072dcc883SBjorn Helgaas 			pnpacpi_encode_io(dev, resource,
9017e2cf31fSBjorn Helgaas 				pnp_get_resource(dev, IORESOURCE_IO, port));
9021da177e4SLinus Torvalds 			port++;
9031da177e4SLinus Torvalds 			break;
90450eca3ebSBob Moore 		case ACPI_RESOURCE_TYPE_FIXED_IO:
90572dcc883SBjorn Helgaas 			pnpacpi_encode_fixed_io(dev, resource,
9067e2cf31fSBjorn Helgaas 				pnp_get_resource(dev, IORESOURCE_IO, port));
9071da177e4SLinus Torvalds 			port++;
9081da177e4SLinus Torvalds 			break;
90950eca3ebSBob Moore 		case ACPI_RESOURCE_TYPE_MEMORY24:
91072dcc883SBjorn Helgaas 			pnpacpi_encode_mem24(dev, resource,
9117e2cf31fSBjorn Helgaas 				pnp_get_resource(dev, IORESOURCE_MEM, mem));
9121da177e4SLinus Torvalds 			mem++;
9131da177e4SLinus Torvalds 			break;
91450eca3ebSBob Moore 		case ACPI_RESOURCE_TYPE_MEMORY32:
91572dcc883SBjorn Helgaas 			pnpacpi_encode_mem32(dev, resource,
9167e2cf31fSBjorn Helgaas 				pnp_get_resource(dev, IORESOURCE_MEM, mem));
9171da177e4SLinus Torvalds 			mem++;
9181da177e4SLinus Torvalds 			break;
91950eca3ebSBob Moore 		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
92072dcc883SBjorn Helgaas 			pnpacpi_encode_fixed_mem32(dev, resource,
9217e2cf31fSBjorn Helgaas 				pnp_get_resource(dev, IORESOURCE_MEM, mem));
9221da177e4SLinus Torvalds 			mem++;
9231da177e4SLinus Torvalds 			break;
9240af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
92572dcc883SBjorn Helgaas 			pnpacpi_encode_ext_irq(dev, resource,
9267e2cf31fSBjorn Helgaas 				pnp_get_resource(dev, IORESOURCE_IRQ, irq));
9270af5853bSLen Brown 			irq++;
9280af5853bSLen Brown 			break;
9290af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
9300af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
9310af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_VENDOR:
9320af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_END_TAG:
9330af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_ADDRESS16:
9340af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_ADDRESS32:
9350af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_ADDRESS64:
9360af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
9370af5853bSLen Brown 		case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
9381da177e4SLinus Torvalds 		default:	/* other type */
9391d7f2cddSAndy Shevchenko 			dev_warn(&dev->dev,
9401d7f2cddSAndy Shevchenko 				 "can't encode unknown resource type %d\n",
9411d7f2cddSAndy Shevchenko 				 resource->type);
9421da177e4SLinus Torvalds 			return -EINVAL;
9431da177e4SLinus Torvalds 		}
9441da177e4SLinus Torvalds 		resource++;
9451da177e4SLinus Torvalds 		i++;
9461da177e4SLinus Torvalds 	}
9471da177e4SLinus Torvalds 	return 0;
9481da177e4SLinus Torvalds }
949