rsparser.c 26.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
/*
 * pnpacpi -- PnP ACPI driver
 *
 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
B
Bob Moore 已提交
6
 *
L
Linus Torvalds 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * 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>
#include <linux/pci.h>
24 25
#include <linux/pnp.h>
#include "../base.h"
L
Linus Torvalds 已提交
26 27 28 29 30 31 32 33 34 35 36
#include "pnpacpi.h"

#ifdef CONFIG_IA64
#define valid_IRQ(i) (1)
#else
#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
#endif

/*
 * Allocated Resources
 */
37
static int irq_flags(int triggering, int polarity, int shareable)
L
Linus Torvalds 已提交
38
{
39 40
	int flags;

B
Bob Moore 已提交
41
	if (triggering == ACPI_LEVEL_SENSITIVE) {
B
Bjorn Helgaas 已提交
42
		if (polarity == ACPI_ACTIVE_LOW)
43
			flags = IORESOURCE_IRQ_LOWLEVEL;
L
Linus Torvalds 已提交
44
		else
45
			flags = IORESOURCE_IRQ_HIGHLEVEL;
B
Bjorn Helgaas 已提交
46
	} else {
B
Bjorn Helgaas 已提交
47
		if (polarity == ACPI_ACTIVE_LOW)
48
			flags = IORESOURCE_IRQ_LOWEDGE;
L
Linus Torvalds 已提交
49
		else
50
			flags = IORESOURCE_IRQ_HIGHEDGE;
L
Linus Torvalds 已提交
51
	}
52 53 54 55 56

	if (shareable)
		flags |= IORESOURCE_IRQ_SHAREABLE;

	return flags;
L
Linus Torvalds 已提交
57 58
}

B
Bob Moore 已提交
59
static void decode_irq_flags(int flag, int *triggering, int *polarity)
L
Linus Torvalds 已提交
60 61 62
{
	switch (flag) {
	case IORESOURCE_IRQ_LOWLEVEL:
B
Bob Moore 已提交
63 64
		*triggering = ACPI_LEVEL_SENSITIVE;
		*polarity = ACPI_ACTIVE_LOW;
L
Linus Torvalds 已提交
65
		break;
B
Bjorn Helgaas 已提交
66
	case IORESOURCE_IRQ_HIGHLEVEL:
B
Bob Moore 已提交
67 68
		*triggering = ACPI_LEVEL_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
L
Linus Torvalds 已提交
69 70
		break;
	case IORESOURCE_IRQ_LOWEDGE:
B
Bob Moore 已提交
71 72
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_LOW;
L
Linus Torvalds 已提交
73 74
		break;
	case IORESOURCE_IRQ_HIGHEDGE:
B
Bob Moore 已提交
75 76
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
L
Linus Torvalds 已提交
77 78 79 80
		break;
	}
}

81
static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
82 83
						u32 gsi, int triggering,
						int polarity, int shareable)
L
Linus Torvalds 已提交
84
{
85
	int irq, flags;
86
	int p, t;
87 88 89 90

	if (!valid_IRQ(gsi))
		return;

91 92 93 94 95 96 97 98 99 100
	/*
	 * in IO-APIC mode, use overrided attribute. Two reasons:
	 * 1. BIOS bug in DSDT
	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
	 */
	if (!acpi_get_override_irq(gsi, &t, &p)) {
		t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
		p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;

		if (triggering != t || polarity != p) {
101
			dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
102 103 104 105 106 107
				gsi, t ? "edge":"level", p ? "low":"high");
			triggering = t;
			polarity = p;
		}
	}

108
	flags = irq_flags(triggering, polarity, shareable);
B
Bob Moore 已提交
109
	irq = acpi_register_gsi(gsi, triggering, polarity);
110 111 112 113
	if (irq >= 0)
		pcibios_penalize_isa_irq(irq, 1);
	else
		flags |= IORESOURCE_DISABLED;
114

115
	pnp_add_irq_resource(dev, irq, flags);
L
Linus Torvalds 已提交
116 117
}

118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
static int dma_flags(int type, int bus_master, int transfer)
{
	int flags = 0;

	if (bus_master)
		flags |= IORESOURCE_DMA_MASTER;
	switch (type) {
	case ACPI_COMPATIBILITY:
		flags |= IORESOURCE_DMA_COMPATIBLE;
		break;
	case ACPI_TYPE_A:
		flags |= IORESOURCE_DMA_TYPEA;
		break;
	case ACPI_TYPE_B:
		flags |= IORESOURCE_DMA_TYPEB;
		break;
	case ACPI_TYPE_F:
		flags |= IORESOURCE_DMA_TYPEF;
		break;
	default:
		/* Set a default value ? */
		flags |= IORESOURCE_DMA_COMPATIBLE;
		pnp_err("Invalid DMA type");
	}
	switch (transfer) {
	case ACPI_TRANSFER_8:
		flags |= IORESOURCE_DMA_8BIT;
		break;
	case ACPI_TRANSFER_8_16:
		flags |= IORESOURCE_DMA_8AND16BIT;
		break;
	case ACPI_TRANSFER_16:
		flags |= IORESOURCE_DMA_16BIT;
		break;
	default:
		/* Set a default value ? */
		flags |= IORESOURCE_DMA_8AND16BIT;
		pnp_err("Invalid DMA transfer type");
	}

	return flags;
}

161 162
static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
					       u64 len, int io_decode)
L
Linus Torvalds 已提交
163
{
164 165
	int flags = 0;
	u64 end = start + len - 1;
B
Bjorn Helgaas 已提交
166

167 168 169 170 171 172
	if (io_decode == ACPI_DECODE_16)
		flags |= PNP_PORT_FLAG_16BITADDR;
	if (len == 0 || end >= 0x10003)
		flags |= IORESOURCE_DISABLED;

	pnp_add_io_resource(dev, start, end, flags);
L
Linus Torvalds 已提交
173 174
}

175
static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
176 177
						u64 mem, u64 len,
						int write_protect)
L
Linus Torvalds 已提交
178
{
179 180
	struct resource *res;
	int i;
181
	static unsigned char warned;
B
Bjorn Helgaas 已提交
182

183 184 185 186 187
	for (i = 0; i < PNP_MAX_MEM; i++) {
		res = pnp_get_resource(dev, IORESOURCE_MEM, i);
		if (!pnp_resource_valid(res))
			break;
	}
L
Linus Torvalds 已提交
188
	if (i < PNP_MAX_MEM) {
189
		res->flags = IORESOURCE_MEM;	// Also clears _UNSET flag
L
Linus Torvalds 已提交
190
		if (len <= 0) {
191
			res->flags |= IORESOURCE_DISABLED;
L
Linus Torvalds 已提交
192 193
			return;
		}
B
Bjorn Helgaas 已提交
194
		if (write_protect == ACPI_READ_WRITE_MEMORY)
195
			res->flags |= IORESOURCE_MEM_WRITEABLE;
196

197 198
		res->start = mem;
		res->end = mem + len - 1;
199
	} else if (!warned) {
200
		printk(KERN_WARNING "pnpacpi: exceeded the max number of mem "
201
				"resources: %d\n", PNP_MAX_MEM);
202
		warned = 1;
L
Linus Torvalds 已提交
203 204 205
	}
}

206
static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
207
						  struct acpi_resource *res)
208 209 210 211 212 213
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;

	status = acpi_resource_to_address64(res, p);
	if (!ACPI_SUCCESS(status)) {
214
		dev_warn(&dev->dev, "failed to convert resource type %d\n",
B
Bjorn Helgaas 已提交
215
			 res->type);
216 217 218
		return;
	}

219 220 221
	if (p->producer_consumer == ACPI_PRODUCER)
		return;

222
	if (p->resource_type == ACPI_MEMORY_RANGE)
223
		pnpacpi_parse_allocated_memresource(dev,
B
Bjorn Helgaas 已提交
224 225
			p->minimum, p->address_length,
			p->info.mem.write_protect);
226
	else if (p->resource_type == ACPI_IO_RANGE)
227
		pnpacpi_parse_allocated_ioresource(dev,
B
Bjorn Helgaas 已提交
228 229 230
			p->minimum, p->address_length,
			p->granularity == 0xfff ? ACPI_DECODE_10 :
				ACPI_DECODE_16);
231
}
L
Linus Torvalds 已提交
232 233

static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
234
					      void *data)
L
Linus Torvalds 已提交
235
{
236
	struct pnp_dev *dev = data;
237 238 239 240 241 242 243 244
	struct acpi_resource_irq *irq;
	struct acpi_resource_dma *dma;
	struct acpi_resource_io *io;
	struct acpi_resource_fixed_io *fixed_io;
	struct acpi_resource_memory24 *memory24;
	struct acpi_resource_memory32 *memory32;
	struct acpi_resource_fixed_memory32 *fixed_memory32;
	struct acpi_resource_extended_irq *extended_irq;
245
	int i, flags;
L
Linus Torvalds 已提交
246

247
	switch (res->type) {
B
Bob Moore 已提交
248
	case ACPI_RESOURCE_TYPE_IRQ:
249 250 251 252
		/*
		 * Per spec, only one interrupt per descriptor is allowed in
		 * _CRS, but some firmware violates this, so parse them all.
		 */
253 254
		irq = &res->data.irq;
		for (i = 0; i < irq->interrupt_count; i++) {
255
			pnpacpi_parse_allocated_irqresource(dev,
256 257 258 259
				irq->interrupts[i],
				irq->triggering,
				irq->polarity,
				irq->sharable);
L
Linus Torvalds 已提交
260 261 262
		}
		break;

B
Bob Moore 已提交
263
	case ACPI_RESOURCE_TYPE_DMA:
264
		dma = &res->data.dma;
265 266 267 268 269 270 271
		if (dma->channel_count > 0) {
			flags = dma_flags(dma->type, dma->bus_master,
					  dma->transfer);
			if (dma->channels[0] == (u8) -1)
				flags |= IORESOURCE_DISABLED;
			pnp_add_dma_resource(dev, dma->channels[0], flags);
		}
L
Linus Torvalds 已提交
272
		break;
273

B
Bob Moore 已提交
274
	case ACPI_RESOURCE_TYPE_IO:
275
		io = &res->data.io;
276
		pnpacpi_parse_allocated_ioresource(dev,
277 278 279
			io->minimum,
			io->address_length,
			io->io_decode);
L
Linus Torvalds 已提交
280
		break;
281 282 283 284 285

	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		break;

B
Bob Moore 已提交
286
	case ACPI_RESOURCE_TYPE_FIXED_IO:
287
		fixed_io = &res->data.fixed_io;
288
		pnpacpi_parse_allocated_ioresource(dev,
289 290
			fixed_io->address,
			fixed_io->address_length,
B
Bjorn Helgaas 已提交
291
			ACPI_DECODE_10);
L
Linus Torvalds 已提交
292
		break;
293 294 295 296 297 298 299

	case ACPI_RESOURCE_TYPE_VENDOR:
		break;

	case ACPI_RESOURCE_TYPE_END_TAG:
		break;

B
Bob Moore 已提交
300
	case ACPI_RESOURCE_TYPE_MEMORY24:
301
		memory24 = &res->data.memory24;
302
		pnpacpi_parse_allocated_memresource(dev,
303 304 305
			memory24->minimum,
			memory24->address_length,
			memory24->write_protect);
L
Linus Torvalds 已提交
306
		break;
B
Bob Moore 已提交
307
	case ACPI_RESOURCE_TYPE_MEMORY32:
308
		memory32 = &res->data.memory32;
309
		pnpacpi_parse_allocated_memresource(dev,
310 311 312
			memory32->minimum,
			memory32->address_length,
			memory32->write_protect);
L
Linus Torvalds 已提交
313
		break;
B
Bob Moore 已提交
314
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
315
		fixed_memory32 = &res->data.fixed_memory32;
316
		pnpacpi_parse_allocated_memresource(dev,
317 318 319
			fixed_memory32->address,
			fixed_memory32->address_length,
			fixed_memory32->write_protect);
L
Linus Torvalds 已提交
320
		break;
B
Bob Moore 已提交
321 322 323
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
324
		pnpacpi_parse_allocated_address_space(dev, res);
L
Linus Torvalds 已提交
325
		break;
326 327

	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
328 329
		if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
			return AE_OK;
330 331 332
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
333 334
		extended_irq = &res->data.extended_irq;
		if (extended_irq->producer_consumer == ACPI_PRODUCER)
335 336
			return AE_OK;

337
		for (i = 0; i < extended_irq->interrupt_count; i++) {
338
			pnpacpi_parse_allocated_irqresource(dev,
339 340 341 342
				extended_irq->interrupts[i],
				extended_irq->triggering,
				extended_irq->polarity,
				extended_irq->sharable);
343 344 345 346
		}
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
L
Linus Torvalds 已提交
347
		break;
348

L
Linus Torvalds 已提交
349
	default:
350 351
		dev_warn(&dev->dev, "unknown resource type %d in _CRS\n",
			 res->type);
L
Linus Torvalds 已提交
352 353
		return AE_ERROR;
	}
B
Bjorn Helgaas 已提交
354

L
Linus Torvalds 已提交
355 356 357
	return AE_OK;
}

358
acpi_status pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
L
Linus Torvalds 已提交
359
{
360 361
	acpi_handle handle = dev->data;

362 363
	dev_dbg(&dev->dev, "parse allocated resources\n");

364
	pnp_init_resources(dev);
L
Linus Torvalds 已提交
365

B
Bjorn Helgaas 已提交
366
	return acpi_walk_resources(handle, METHOD_NAME__CRS,
367
				   pnpacpi_allocated_resource, dev);
L
Linus Torvalds 已提交
368 369
}

370 371
static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
					    struct pnp_option *option,
372
					    struct acpi_resource_dma *p)
L
Linus Torvalds 已提交
373 374
{
	int i;
B
Bjorn Helgaas 已提交
375
	struct pnp_dma *dma;
L
Linus Torvalds 已提交
376

B
Bob Moore 已提交
377
	if (p->channel_count == 0)
L
Linus Torvalds 已提交
378
		return;
379
	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
L
Linus Torvalds 已提交
380 381 382
	if (!dma)
		return;

B
Bjorn Helgaas 已提交
383
	for (i = 0; i < p->channel_count; i++)
L
Linus Torvalds 已提交
384
		dma->map |= 1 << p->channels[i];
385 386

	dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
L
Linus Torvalds 已提交
387

388
	pnp_register_dma_resource(dev, option, dma);
L
Linus Torvalds 已提交
389 390
}

391 392
static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
					    struct pnp_option *option,
393
					    struct acpi_resource_irq *p)
L
Linus Torvalds 已提交
394 395
{
	int i;
B
Bjorn Helgaas 已提交
396 397
	struct pnp_irq *irq;

B
Bob Moore 已提交
398
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
399
		return;
400
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
401 402 403
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
404
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
405 406
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
407
	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
L
Linus Torvalds 已提交
408

409
	pnp_register_irq_resource(dev, option, irq);
L
Linus Torvalds 已提交
410 411
}

412 413
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
						struct pnp_option *option,
414
					struct acpi_resource_extended_irq *p)
L
Linus Torvalds 已提交
415 416
{
	int i;
B
Bjorn Helgaas 已提交
417
	struct pnp_irq *irq;
L
Linus Torvalds 已提交
418

B
Bob Moore 已提交
419
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
420
		return;
421
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
422 423 424
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
425
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
426 427
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
428
	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
L
Linus Torvalds 已提交
429

430
	pnp_register_irq_resource(dev, option, irq);
L
Linus Torvalds 已提交
431 432
}

433 434
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
					     struct pnp_option *option,
435
					     struct acpi_resource_io *io)
L
Linus Torvalds 已提交
436
{
B
Bjorn Helgaas 已提交
437
	struct pnp_port *port;
L
Linus Torvalds 已提交
438

B
Bob Moore 已提交
439
	if (io->address_length == 0)
L
Linus Torvalds 已提交
440
		return;
441
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
442 443
	if (!port)
		return;
B
Bob Moore 已提交
444 445
	port->min = io->minimum;
	port->max = io->maximum;
L
Linus Torvalds 已提交
446
	port->align = io->alignment;
B
Bob Moore 已提交
447 448
	port->size = io->address_length;
	port->flags = ACPI_DECODE_16 == io->io_decode ?
B
Bjorn Helgaas 已提交
449
	    PNP_PORT_FLAG_16BITADDR : 0;
450
	pnp_register_port_resource(dev, option, port);
L
Linus Torvalds 已提交
451 452
}

453 454
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
						   struct pnp_option *option,
455
					struct acpi_resource_fixed_io *io)
L
Linus Torvalds 已提交
456
{
B
Bjorn Helgaas 已提交
457
	struct pnp_port *port;
L
Linus Torvalds 已提交
458

B
Bob Moore 已提交
459
	if (io->address_length == 0)
L
Linus Torvalds 已提交
460
		return;
461
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
462 463
	if (!port)
		return;
B
Bob Moore 已提交
464 465
	port->min = port->max = io->address;
	port->size = io->address_length;
L
Linus Torvalds 已提交
466 467
	port->align = 0;
	port->flags = PNP_PORT_FLAG_FIXED;
468
	pnp_register_port_resource(dev, option, port);
L
Linus Torvalds 已提交
469 470
}

471 472
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
					      struct pnp_option *option,
473
					      struct acpi_resource_memory24 *p)
L
Linus Torvalds 已提交
474
{
B
Bjorn Helgaas 已提交
475
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
476

B
Bob Moore 已提交
477
	if (p->address_length == 0)
L
Linus Torvalds 已提交
478
		return;
479
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
480 481
	if (!mem)
		return;
B
Bob Moore 已提交
482 483
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
484
	mem->align = p->alignment;
B
Bob Moore 已提交
485
	mem->size = p->address_length;
L
Linus Torvalds 已提交
486

B
Bob Moore 已提交
487
	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
B
Bjorn Helgaas 已提交
488
	    IORESOURCE_MEM_WRITEABLE : 0;
L
Linus Torvalds 已提交
489

490
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
491 492
}

493 494
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
					      struct pnp_option *option,
495
					      struct acpi_resource_memory32 *p)
L
Linus Torvalds 已提交
496
{
B
Bjorn Helgaas 已提交
497
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
498

B
Bob Moore 已提交
499
	if (p->address_length == 0)
L
Linus Torvalds 已提交
500
		return;
501
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
502 503
	if (!mem)
		return;
B
Bob Moore 已提交
504 505
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
506
	mem->align = p->alignment;
B
Bob Moore 已提交
507
	mem->size = p->address_length;
L
Linus Torvalds 已提交
508

B
Bob Moore 已提交
509
	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
B
Bjorn Helgaas 已提交
510
	    IORESOURCE_MEM_WRITEABLE : 0;
L
Linus Torvalds 已提交
511

512
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
513 514
}

515 516
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
						    struct pnp_option *option,
517
					struct acpi_resource_fixed_memory32 *p)
L
Linus Torvalds 已提交
518
{
B
Bjorn Helgaas 已提交
519
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
520

B
Bob Moore 已提交
521
	if (p->address_length == 0)
L
Linus Torvalds 已提交
522
		return;
523
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
524 525
	if (!mem)
		return;
B
Bob Moore 已提交
526 527
	mem->min = mem->max = p->address;
	mem->size = p->address_length;
L
Linus Torvalds 已提交
528 529
	mem->align = 0;

B
Bob Moore 已提交
530
	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
B
Bjorn Helgaas 已提交
531
	    IORESOURCE_MEM_WRITEABLE : 0;
L
Linus Torvalds 已提交
532

533
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
534 535
}

536 537
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
						struct pnp_option *option,
538
						struct acpi_resource *r)
539 540 541
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
B
Bjorn Helgaas 已提交
542 543
	struct pnp_mem *mem;
	struct pnp_port *port;
544 545 546

	status = acpi_resource_to_address64(r, p);
	if (!ACPI_SUCCESS(status)) {
B
Bjorn Helgaas 已提交
547 548
		pnp_warn("PnPACPI: failed to convert resource type %d",
			 r->type);
549 550 551 552 553 554 555
		return;
	}

	if (p->address_length == 0)
		return;

	if (p->resource_type == ACPI_MEMORY_RANGE) {
556
		mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
557 558
		if (!mem)
			return;
L
Len Brown 已提交
559
		mem->min = mem->max = p->minimum;
560 561
		mem->size = p->address_length;
		mem->align = 0;
L
Len Brown 已提交
562
		mem->flags = (p->info.mem.write_protect ==
B
Bjorn Helgaas 已提交
563 564
			      ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
		    : 0;
565
		pnp_register_mem_resource(dev, option, mem);
566
	} else if (p->resource_type == ACPI_IO_RANGE) {
567
		port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
568 569
		if (!port)
			return;
L
Len Brown 已提交
570
		port->min = port->max = p->minimum;
571 572 573
		port->size = p->address_length;
		port->align = 0;
		port->flags = PNP_PORT_FLAG_FIXED;
574
		pnp_register_port_resource(dev, option, port);
575 576 577
	}
}

L
Linus Torvalds 已提交
578 579
struct acpipnp_parse_option_s {
	struct pnp_option *option;
M
Matthieu Castet 已提交
580
	struct pnp_option *option_independent;
L
Linus Torvalds 已提交
581 582 583
	struct pnp_dev *dev;
};

584 585
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
						  void *data)
L
Linus Torvalds 已提交
586 587
{
	int priority = 0;
588
	struct acpipnp_parse_option_s *parse_data = data;
L
Linus Torvalds 已提交
589 590 591
	struct pnp_dev *dev = parse_data->dev;
	struct pnp_option *option = parse_data->option;

592
	switch (res->type) {
B
Bjorn Helgaas 已提交
593
	case ACPI_RESOURCE_TYPE_IRQ:
594
		pnpacpi_parse_irq_option(dev, option, &res->data.irq);
B
Bjorn Helgaas 已提交
595
		break;
596

B
Bjorn Helgaas 已提交
597
	case ACPI_RESOURCE_TYPE_DMA:
598
		pnpacpi_parse_dma_option(dev, option, &res->data.dma);
B
Bjorn Helgaas 已提交
599
		break;
600

B
Bjorn Helgaas 已提交
601 602 603 604
	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
		switch (res->data.start_dpf.compatibility_priority) {
		case ACPI_GOOD_CONFIGURATION:
			priority = PNP_RES_PRIORITY_PREFERRED;
L
Linus Torvalds 已提交
605
			break;
606

B
Bjorn Helgaas 已提交
607 608
		case ACPI_ACCEPTABLE_CONFIGURATION:
			priority = PNP_RES_PRIORITY_ACCEPTABLE;
M
Matthieu Castet 已提交
609
			break;
610

B
Bjorn Helgaas 已提交
611 612
		case ACPI_SUB_OPTIMAL_CONFIGURATION:
			priority = PNP_RES_PRIORITY_FUNCTIONAL;
613
			break;
B
Bjorn Helgaas 已提交
614 615
		default:
			priority = PNP_RES_PRIORITY_INVALID;
616
			break;
B
Bjorn Helgaas 已提交
617
		}
B
Bjorn Helgaas 已提交
618
		/* TBD: Consider performance/robustness bits */
B
Bjorn Helgaas 已提交
619 620 621 622 623
		option = pnp_register_dependent_option(dev, priority);
		if (!option)
			return AE_ERROR;
		parse_data->option = option;
		break;
624

B
Bjorn Helgaas 已提交
625 626 627
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		/*only one EndDependentFn is allowed */
		if (!parse_data->option_independent) {
628 629
			dev_warn(&dev->dev, "more than one EndDependentFn "
				 "in _PRS\n");
B
Bjorn Helgaas 已提交
630 631 632 633
			return AE_ERROR;
		}
		parse_data->option = parse_data->option_independent;
		parse_data->option_independent = NULL;
634
		dev_dbg(&dev->dev, "end dependent options\n");
B
Bjorn Helgaas 已提交
635
		break;
636

B
Bjorn Helgaas 已提交
637
	case ACPI_RESOURCE_TYPE_IO:
638
		pnpacpi_parse_port_option(dev, option, &res->data.io);
B
Bjorn Helgaas 已提交
639
		break;
640

B
Bjorn Helgaas 已提交
641
	case ACPI_RESOURCE_TYPE_FIXED_IO:
642 643
		pnpacpi_parse_fixed_port_option(dev, option,
					        &res->data.fixed_io);
B
Bjorn Helgaas 已提交
644
		break;
645

B
Bjorn Helgaas 已提交
646 647 648
	case ACPI_RESOURCE_TYPE_VENDOR:
	case ACPI_RESOURCE_TYPE_END_TAG:
		break;
649

B
Bjorn Helgaas 已提交
650
	case ACPI_RESOURCE_TYPE_MEMORY24:
651
		pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
B
Bjorn Helgaas 已提交
652
		break;
653

B
Bjorn Helgaas 已提交
654
	case ACPI_RESOURCE_TYPE_MEMORY32:
655
		pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
B
Bjorn Helgaas 已提交
656
		break;
657

B
Bjorn Helgaas 已提交
658
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
659
		pnpacpi_parse_fixed_mem32_option(dev, option,
B
Bjorn Helgaas 已提交
660 661
						 &res->data.fixed_memory32);
		break;
662

B
Bjorn Helgaas 已提交
663 664 665
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
666
		pnpacpi_parse_address_option(dev, option, res);
B
Bjorn Helgaas 已提交
667
		break;
668

B
Bjorn Helgaas 已提交
669 670 671 672
	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
673 674
		pnpacpi_parse_ext_irq_option(dev, option,
					     &res->data.extended_irq);
B
Bjorn Helgaas 已提交
675 676 677 678 679 680
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
		break;

	default:
681 682
		dev_warn(&dev->dev, "unknown resource type %d in _PRS\n",
			 res->type);
B
Bjorn Helgaas 已提交
683
		return AE_ERROR;
L
Linus Torvalds 已提交
684
	}
B
Bjorn Helgaas 已提交
685

L
Linus Torvalds 已提交
686 687 688
	return AE_OK;
}

689
acpi_status __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
L
Linus Torvalds 已提交
690
{
691
	acpi_handle handle = dev->data;
L
Linus Torvalds 已提交
692 693 694
	acpi_status status;
	struct acpipnp_parse_option_s parse_data;

695 696
	dev_dbg(&dev->dev, "parse resource options\n");

L
Linus Torvalds 已提交
697 698 699
	parse_data.option = pnp_register_independent_option(dev);
	if (!parse_data.option)
		return AE_ERROR;
M
Matthieu Castet 已提交
700
	parse_data.option_independent = parse_data.option;
L
Linus Torvalds 已提交
701
	parse_data.dev = dev;
B
Bob Moore 已提交
702
	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
B
Bjorn Helgaas 已提交
703
				     pnpacpi_option_resource, &parse_data);
L
Linus Torvalds 已提交
704 705 706 707

	return status;
}

708
static int pnpacpi_supported_resource(struct acpi_resource *res)
L
Linus Torvalds 已提交
709
{
710
	switch (res->type) {
B
Bob Moore 已提交
711 712 713 714 715 716 717 718 719 720
	case ACPI_RESOURCE_TYPE_IRQ:
	case ACPI_RESOURCE_TYPE_DMA:
	case ACPI_RESOURCE_TYPE_IO:
	case ACPI_RESOURCE_TYPE_FIXED_IO:
	case ACPI_RESOURCE_TYPE_MEMORY24:
	case ACPI_RESOURCE_TYPE_MEMORY32:
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
721
	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
722
		return 1;
L
Linus Torvalds 已提交
723
	}
724 725 726 727 728 729 730
	return 0;
}

/*
 * Set resource
 */
static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
731
					   void *data)
732
{
733
	int *res_cnt = data;
734 735 736

	if (pnpacpi_supported_resource(res))
		(*res_cnt)++;
L
Linus Torvalds 已提交
737 738 739
	return AE_OK;
}

B
Bjorn Helgaas 已提交
740
static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
L
Linus Torvalds 已提交
741
{
742
	struct acpi_resource **resource = data;
743 744

	if (pnpacpi_supported_resource(res)) {
745
		(*resource)->type = res->type;
746
		(*resource)->length = sizeof(struct acpi_resource);
L
Linus Torvalds 已提交
747 748 749 750 751 752
		(*resource)++;
	}

	return AE_OK;
}

753
int pnpacpi_build_resource_template(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
754
				    struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
755
{
756
	acpi_handle handle = dev->data;
L
Linus Torvalds 已提交
757 758 759 760
	struct acpi_resource *resource;
	int res_cnt = 0;
	acpi_status status;

B
Bob Moore 已提交
761
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
762
				     pnpacpi_count_resources, &res_cnt);
L
Linus Torvalds 已提交
763
	if (ACPI_FAILURE(status)) {
764
		dev_err(&dev->dev, "can't evaluate _CRS\n");
L
Linus Torvalds 已提交
765 766 767 768 769
		return -EINVAL;
	}
	if (!res_cnt)
		return -EINVAL;
	buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
770
	buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
L
Linus Torvalds 已提交
771 772
	if (!buffer->pointer)
		return -ENOMEM;
773

L
Linus Torvalds 已提交
774
	resource = (struct acpi_resource *)buffer->pointer;
B
Bob Moore 已提交
775
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
776
				     pnpacpi_type_resources, &resource);
L
Linus Torvalds 已提交
777 778
	if (ACPI_FAILURE(status)) {
		kfree(buffer->pointer);
779
		dev_err(&dev->dev, "can't evaluate _CRS\n");
L
Linus Torvalds 已提交
780 781 782
		return -EINVAL;
	}
	/* resource will pointer the end resource now */
B
Bob Moore 已提交
783
	resource->type = ACPI_RESOURCE_TYPE_END_TAG;
L
Linus Torvalds 已提交
784 785 786 787

	return 0;
}

788 789
static void pnpacpi_encode_irq(struct pnp_dev *dev,
			       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
790
			       struct resource *p)
L
Linus Torvalds 已提交
791
{
792
	struct acpi_resource_irq *irq = &resource->data.irq;
B
Bob Moore 已提交
793
	int triggering, polarity;
B
Bjorn Helgaas 已提交
794 795

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
796 797
	irq->triggering = triggering;
	irq->polarity = polarity;
B
Bob Moore 已提交
798
	if (triggering == ACPI_EDGE_SENSITIVE)
799
		irq->sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
800
	else
801 802 803
		irq->sharable = ACPI_SHARED;
	irq->interrupt_count = 1;
	irq->interrupts[0] = p->start;
804 805 806 807 808

	dev_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",
		irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
L
Linus Torvalds 已提交
809 810
}

811 812
static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
				   struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
813
				   struct resource *p)
L
Linus Torvalds 已提交
814
{
815
	struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
B
Bob Moore 已提交
816
	int triggering, polarity;
B
Bjorn Helgaas 已提交
817 818

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
819 820 821
	extended_irq->producer_consumer = ACPI_CONSUMER;
	extended_irq->triggering = triggering;
	extended_irq->polarity = polarity;
B
Bob Moore 已提交
822
	if (triggering == ACPI_EDGE_SENSITIVE)
823
		extended_irq->sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
824
	else
825 826 827
		extended_irq->sharable = ACPI_SHARED;
	extended_irq->interrupt_count = 1;
	extended_irq->interrupts[0] = p->start;
828 829 830 831 832

	dev_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");
L
Linus Torvalds 已提交
833 834
}

835 836
static void pnpacpi_encode_dma(struct pnp_dev *dev,
			       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
837
			       struct resource *p)
L
Linus Torvalds 已提交
838
{
839 840
	struct acpi_resource_dma *dma = &resource->data.dma;

L
Linus Torvalds 已提交
841
	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
842
	switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
B
Bjorn Helgaas 已提交
843
	case IORESOURCE_DMA_TYPEA:
844
		dma->type = ACPI_TYPE_A;
B
Bjorn Helgaas 已提交
845 846
		break;
	case IORESOURCE_DMA_TYPEB:
847
		dma->type = ACPI_TYPE_B;
B
Bjorn Helgaas 已提交
848 849
		break;
	case IORESOURCE_DMA_TYPEF:
850
		dma->type = ACPI_TYPE_F;
B
Bjorn Helgaas 已提交
851 852
		break;
	default:
853
		dma->type = ACPI_COMPATIBILITY;
854 855 856
	}

	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
B
Bjorn Helgaas 已提交
857
	case IORESOURCE_DMA_8BIT:
858
		dma->transfer = ACPI_TRANSFER_8;
B
Bjorn Helgaas 已提交
859 860
		break;
	case IORESOURCE_DMA_8AND16BIT:
861
		dma->transfer = ACPI_TRANSFER_8_16;
B
Bjorn Helgaas 已提交
862 863
		break;
	default:
864
		dma->transfer = ACPI_TRANSFER_16;
865 866
	}

867 868 869
	dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
	dma->channel_count = 1;
	dma->channels[0] = p->start;
870 871 872 873

	dev_dbg(&dev->dev, "  encode dma %d "
		"type %#x transfer %#x master %d\n",
		(int) p->start, dma->type, dma->transfer, dma->bus_master);
L
Linus Torvalds 已提交
874 875
}

876 877
static void pnpacpi_encode_io(struct pnp_dev *dev,
			      struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
878
			      struct resource *p)
L
Linus Torvalds 已提交
879
{
880 881
	struct acpi_resource_io *io = &resource->data.io;

L
Linus Torvalds 已提交
882
	/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
883
	io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
B
Bjorn Helgaas 已提交
884
	    ACPI_DECODE_16 : ACPI_DECODE_10;
885 886 887 888
	io->minimum = p->start;
	io->maximum = p->end;
	io->alignment = 0;	/* Correct? */
	io->address_length = p->end - p->start + 1;
889 890 891 892

	dev_dbg(&dev->dev, "  encode io %#llx-%#llx decode %#x\n",
		(unsigned long long) p->start, (unsigned long long) p->end,
		io->io_decode);
L
Linus Torvalds 已提交
893 894
}

895 896
static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
				    struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
897
				    struct resource *p)
L
Linus Torvalds 已提交
898
{
899 900 901 902
	struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;

	fixed_io->address = p->start;
	fixed_io->address_length = p->end - p->start + 1;
903 904 905

	dev_dbg(&dev->dev, "  encode fixed_io %#llx-%#llx\n",
		(unsigned long long) p->start, (unsigned long long) p->end);
L
Linus Torvalds 已提交
906 907
}

908 909
static void pnpacpi_encode_mem24(struct pnp_dev *dev,
				 struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
910
				 struct resource *p)
L
Linus Torvalds 已提交
911
{
912 913
	struct acpi_resource_memory24 *memory24 = &resource->data.memory24;

L
Linus Torvalds 已提交
914
	/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
915
	memory24->write_protect =
B
Bjorn Helgaas 已提交
916 917
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
918 919 920 921
	memory24->minimum = p->start;
	memory24->maximum = p->end;
	memory24->alignment = 0;
	memory24->address_length = p->end - p->start + 1;
922 923 924 925

	dev_dbg(&dev->dev, "  encode mem24 %#llx-%#llx write_protect %#x\n",
		(unsigned long long) p->start, (unsigned long long) p->end,
		memory24->write_protect);
L
Linus Torvalds 已提交
926 927
}

928 929
static void pnpacpi_encode_mem32(struct pnp_dev *dev,
				 struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
930
				 struct resource *p)
L
Linus Torvalds 已提交
931
{
932 933 934
	struct acpi_resource_memory32 *memory32 = &resource->data.memory32;

	memory32->write_protect =
B
Bjorn Helgaas 已提交
935 936
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
937 938 939 940
	memory32->minimum = p->start;
	memory32->maximum = p->end;
	memory32->alignment = 0;
	memory32->address_length = p->end - p->start + 1;
941 942 943 944

	dev_dbg(&dev->dev, "  encode mem32 %#llx-%#llx write_protect %#x\n",
		(unsigned long long) p->start, (unsigned long long) p->end,
		memory32->write_protect);
L
Linus Torvalds 已提交
945 946
}

947 948
static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
				       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
949
				       struct resource *p)
L
Linus Torvalds 已提交
950
{
951 952 953
	struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;

	fixed_memory32->write_protect =
B
Bjorn Helgaas 已提交
954 955
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
956 957
	fixed_memory32->address = p->start;
	fixed_memory32->address_length = p->end - p->start + 1;
958 959 960 961 962

	dev_dbg(&dev->dev, "  encode fixed_mem32 %#llx-%#llx "
		"write_protect %#x\n",
		(unsigned long long) p->start, (unsigned long long) p->end,
		fixed_memory32->write_protect);
L
Linus Torvalds 已提交
963 964
}

965
int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
966 967 968
{
	int i = 0;
	/* pnpacpi_build_resource_template allocates extra mem */
B
Bjorn Helgaas 已提交
969
	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
970
	struct acpi_resource *resource = buffer->pointer;
L
Linus Torvalds 已提交
971 972
	int port = 0, irq = 0, dma = 0, mem = 0;

973
	dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
L
Linus Torvalds 已提交
974
	while (i < res_cnt) {
B
Bjorn Helgaas 已提交
975
		switch (resource->type) {
B
Bob Moore 已提交
976
		case ACPI_RESOURCE_TYPE_IRQ:
977
			pnpacpi_encode_irq(dev, resource,
978
			       pnp_get_resource(dev, IORESOURCE_IRQ, irq));
L
Linus Torvalds 已提交
979 980 981
			irq++;
			break;

B
Bob Moore 已提交
982
		case ACPI_RESOURCE_TYPE_DMA:
983
			pnpacpi_encode_dma(dev, resource,
984
				pnp_get_resource(dev, IORESOURCE_DMA, dma));
B
Bjorn Helgaas 已提交
985
			dma++;
L
Linus Torvalds 已提交
986
			break;
B
Bob Moore 已提交
987
		case ACPI_RESOURCE_TYPE_IO:
988
			pnpacpi_encode_io(dev, resource,
989
				pnp_get_resource(dev, IORESOURCE_IO, port));
B
Bjorn Helgaas 已提交
990
			port++;
L
Linus Torvalds 已提交
991
			break;
B
Bob Moore 已提交
992
		case ACPI_RESOURCE_TYPE_FIXED_IO:
993
			pnpacpi_encode_fixed_io(dev, resource,
994
				pnp_get_resource(dev, IORESOURCE_IO, port));
B
Bjorn Helgaas 已提交
995
			port++;
L
Linus Torvalds 已提交
996
			break;
B
Bob Moore 已提交
997
		case ACPI_RESOURCE_TYPE_MEMORY24:
998
			pnpacpi_encode_mem24(dev, resource,
999
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
B
Bjorn Helgaas 已提交
1000
			mem++;
L
Linus Torvalds 已提交
1001
			break;
B
Bob Moore 已提交
1002
		case ACPI_RESOURCE_TYPE_MEMORY32:
1003
			pnpacpi_encode_mem32(dev, resource,
1004
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
B
Bjorn Helgaas 已提交
1005
			mem++;
L
Linus Torvalds 已提交
1006
			break;
B
Bob Moore 已提交
1007
		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
1008
			pnpacpi_encode_fixed_mem32(dev, resource,
1009
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
B
Bjorn Helgaas 已提交
1010
			mem++;
L
Linus Torvalds 已提交
1011
			break;
1012
		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
1013
			pnpacpi_encode_ext_irq(dev, resource,
1014
				pnp_get_resource(dev, IORESOURCE_IRQ, irq));
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
			irq++;
			break;
		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		case ACPI_RESOURCE_TYPE_VENDOR:
		case ACPI_RESOURCE_TYPE_END_TAG:
		case ACPI_RESOURCE_TYPE_ADDRESS16:
		case ACPI_RESOURCE_TYPE_ADDRESS32:
		case ACPI_RESOURCE_TYPE_ADDRESS64:
		case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
B
Bjorn Helgaas 已提交
1026
		default:	/* other type */
1027 1028
			dev_warn(&dev->dev, "can't encode unknown resource "
				 "type %d\n", resource->type);
L
Linus Torvalds 已提交
1029 1030
			return -EINVAL;
		}
B
Bjorn Helgaas 已提交
1031 1032
		resource++;
		i++;
L
Linus Torvalds 已提交
1033 1034 1035
	}
	return 0;
}