rsparser.c 28.3 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
	if (shareable == ACPI_SHARED)
54 55 56
		flags |= IORESOURCE_IRQ_SHAREABLE;

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

B
Bjorn Helgaas 已提交
59
static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering,
60
			     int *polarity, int *shareable)
L
Linus Torvalds 已提交
61
{
B
Bjorn Helgaas 已提交
62 63
	switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL |
			 IORESOURCE_IRQ_LOWEDGE  | IORESOURCE_IRQ_HIGHEDGE)) {
L
Linus Torvalds 已提交
64
	case IORESOURCE_IRQ_LOWLEVEL:
B
Bob Moore 已提交
65 66
		*triggering = ACPI_LEVEL_SENSITIVE;
		*polarity = ACPI_ACTIVE_LOW;
L
Linus Torvalds 已提交
67
		break;
B
Bjorn Helgaas 已提交
68
	case IORESOURCE_IRQ_HIGHLEVEL:
B
Bob Moore 已提交
69 70
		*triggering = ACPI_LEVEL_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
L
Linus Torvalds 已提交
71 72
		break;
	case IORESOURCE_IRQ_LOWEDGE:
B
Bob Moore 已提交
73 74
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_LOW;
L
Linus Torvalds 已提交
75 76
		break;
	case IORESOURCE_IRQ_HIGHEDGE:
B
Bob Moore 已提交
77 78
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
L
Linus Torvalds 已提交
79
		break;
B
Bjorn Helgaas 已提交
80 81 82 83 84 85
	default:
		dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n",
			flags);
		*triggering = ACPI_EDGE_SENSITIVE;
		*polarity = ACPI_ACTIVE_HIGH;
		break;
L
Linus Torvalds 已提交
86
	}
87 88 89 90 91

	if (flags & IORESOURCE_IRQ_SHAREABLE)
		*shareable = ACPI_SHARED;
	else
		*shareable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
92 93
}

94
static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
95 96
						u32 gsi, int triggering,
						int polarity, int shareable)
L
Linus Torvalds 已提交
97
{
98
	int irq, flags;
99
	int p, t;
100

101 102
	if (!valid_IRQ(gsi)) {
		pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
103
		return;
104
	}
105

106 107 108 109 110 111 112 113 114 115
	/*
	 * 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) {
116
			dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
117 118 119 120 121 122
				gsi, t ? "edge":"level", p ? "low":"high");
			triggering = t;
			polarity = p;
		}
	}

123
	flags = irq_flags(triggering, polarity, shareable);
B
Bob Moore 已提交
124
	irq = acpi_register_gsi(gsi, triggering, polarity);
125 126 127 128
	if (irq >= 0)
		pcibios_penalize_isa_irq(irq, 1);
	else
		flags |= IORESOURCE_DISABLED;
129

130
	pnp_add_irq_resource(dev, irq, flags);
L
Linus Torvalds 已提交
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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
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;
}

176 177
static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
					       u64 len, int io_decode)
L
Linus Torvalds 已提交
178
{
179 180
	int flags = 0;
	u64 end = start + len - 1;
B
Bjorn Helgaas 已提交
181

182
	if (io_decode == ACPI_DECODE_16)
183
		flags |= IORESOURCE_IO_16BIT_ADDR;
184 185 186 187
	if (len == 0 || end >= 0x10003)
		flags |= IORESOURCE_DISABLED;

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

190
static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
191
						u64 start, u64 len,
B
Bjorn Helgaas 已提交
192
						int write_protect)
L
Linus Torvalds 已提交
193
{
194 195 196 197 198 199 200 201 202
	int flags = 0;
	u64 end = start + len - 1;

	if (len == 0)
		flags |= IORESOURCE_DISABLED;
	if (write_protect == ACPI_READ_WRITE_MEMORY)
		flags |= IORESOURCE_MEM_WRITEABLE;

	pnp_add_mem_resource(dev, start, end, flags);
L
Linus Torvalds 已提交
203 204
}

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

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

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

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

static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
233
					      void *data)
L
Linus Torvalds 已提交
234
{
235
	struct pnp_dev *dev = data;
236 237 238 239 240 241 242 243
	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;
244
	int i, flags;
L
Linus Torvalds 已提交
245

246
	switch (res->type) {
B
Bob Moore 已提交
247
	case ACPI_RESOURCE_TYPE_IRQ:
248 249 250 251
		/*
		 * Per spec, only one interrupt per descriptor is allowed in
		 * _CRS, but some firmware violates this, so parse them all.
		 */
252
		irq = &res->data.irq;
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
		if (irq->interrupt_count == 0)
			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
		else {
			for (i = 0; i < irq->interrupt_count; i++) {
				pnpacpi_parse_allocated_irqresource(dev,
					irq->interrupts[i],
					irq->triggering,
					irq->polarity,
				    irq->sharable);
			}

			/*
			 * The IRQ encoder puts a single interrupt in each
			 * descriptor, so if a _CRS descriptor has more than
			 * one interrupt, we won't be able to re-encode it.
			 */
			if (pnp_can_write(dev) && irq->interrupt_count > 1) {
				dev_warn(&dev->dev, "multiple interrupts in "
					 "_CRS descriptor; configuration can't "
					 "be changed\n");
				dev->capabilities &= ~PNP_WRITE;
			}
L
Linus Torvalds 已提交
275 276 277
		}
		break;

B
Bob Moore 已提交
278
	case ACPI_RESOURCE_TYPE_DMA:
279
		dma = &res->data.dma;
280
		if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
281 282
			flags = dma_flags(dma->type, dma->bus_master,
					  dma->transfer);
283 284 285
		else
			flags = IORESOURCE_DISABLED;
		pnp_add_dma_resource(dev, dma->channels[0], flags);
L
Linus Torvalds 已提交
286
		break;
287

B
Bob Moore 已提交
288
	case ACPI_RESOURCE_TYPE_IO:
289
		io = &res->data.io;
290
		pnpacpi_parse_allocated_ioresource(dev,
291 292 293
			io->minimum,
			io->address_length,
			io->io_decode);
L
Linus Torvalds 已提交
294
		break;
295 296 297 298 299

	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		break;

B
Bob Moore 已提交
300
	case ACPI_RESOURCE_TYPE_FIXED_IO:
301
		fixed_io = &res->data.fixed_io;
302
		pnpacpi_parse_allocated_ioresource(dev,
303 304
			fixed_io->address,
			fixed_io->address_length,
B
Bjorn Helgaas 已提交
305
			ACPI_DECODE_10);
L
Linus Torvalds 已提交
306
		break;
307 308 309 310 311 312 313

	case ACPI_RESOURCE_TYPE_VENDOR:
		break;

	case ACPI_RESOURCE_TYPE_END_TAG:
		break;

B
Bob Moore 已提交
314
	case ACPI_RESOURCE_TYPE_MEMORY24:
315
		memory24 = &res->data.memory24;
316
		pnpacpi_parse_allocated_memresource(dev,
317 318 319
			memory24->minimum,
			memory24->address_length,
			memory24->write_protect);
L
Linus Torvalds 已提交
320
		break;
B
Bob Moore 已提交
321
	case ACPI_RESOURCE_TYPE_MEMORY32:
322
		memory32 = &res->data.memory32;
323
		pnpacpi_parse_allocated_memresource(dev,
324 325 326
			memory32->minimum,
			memory32->address_length,
			memory32->write_protect);
L
Linus Torvalds 已提交
327
		break;
B
Bob Moore 已提交
328
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
329
		fixed_memory32 = &res->data.fixed_memory32;
330
		pnpacpi_parse_allocated_memresource(dev,
331 332 333
			fixed_memory32->address,
			fixed_memory32->address_length,
			fixed_memory32->write_protect);
L
Linus Torvalds 已提交
334
		break;
B
Bob Moore 已提交
335 336 337
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
338
		pnpacpi_parse_allocated_address_space(dev, res);
L
Linus Torvalds 已提交
339
		break;
340 341

	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
342 343
		if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
			return AE_OK;
344 345 346
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
347 348
		extended_irq = &res->data.extended_irq;
		if (extended_irq->producer_consumer == ACPI_PRODUCER)
349 350
			return AE_OK;

351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
		if (extended_irq->interrupt_count == 0)
			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
		else {
			for (i = 0; i < extended_irq->interrupt_count; i++) {
				pnpacpi_parse_allocated_irqresource(dev,
					extended_irq->interrupts[i],
					extended_irq->triggering,
					extended_irq->polarity,
					extended_irq->sharable);
			}

			/*
			 * The IRQ encoder puts a single interrupt in each
			 * descriptor, so if a _CRS descriptor has more than
			 * one interrupt, we won't be able to re-encode it.
			 */
			if (pnp_can_write(dev) &&
			    extended_irq->interrupt_count > 1) {
				dev_warn(&dev->dev, "multiple interrupts in "
					 "_CRS descriptor; configuration can't "
					 "be changed\n");
				dev->capabilities &= ~PNP_WRITE;
			}
374 375 376 377
		}
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
L
Linus Torvalds 已提交
378
		break;
379

L
Linus Torvalds 已提交
380
	default:
381 382
		dev_warn(&dev->dev, "unknown resource type %d in _CRS\n",
			 res->type);
L
Linus Torvalds 已提交
383 384
		return AE_ERROR;
	}
B
Bjorn Helgaas 已提交
385

L
Linus Torvalds 已提交
386 387 388
	return AE_OK;
}

389
int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
L
Linus Torvalds 已提交
390
{
391
	acpi_handle handle = dev->data;
392
	acpi_status status;
393

394 395
	dev_dbg(&dev->dev, "parse allocated resources\n");

396
	pnp_init_resources(dev);
L
Linus Torvalds 已提交
397

398 399 400 401 402 403 404 405 406
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
				     pnpacpi_allocated_resource, dev);

	if (ACPI_FAILURE(status)) {
		if (status != AE_NOT_FOUND)
			dev_err(&dev->dev, "can't evaluate _CRS: %d", status);
		return -EPERM;
	}
	return 0;
L
Linus Torvalds 已提交
407 408
}

409 410
static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
					    struct pnp_option *option,
411
					    struct acpi_resource_dma *p)
L
Linus Torvalds 已提交
412 413
{
	int i;
414
	unsigned char map = 0, flags;
L
Linus Torvalds 已提交
415

B
Bob Moore 已提交
416
	if (p->channel_count == 0)
L
Linus Torvalds 已提交
417 418
		return;

B
Bjorn Helgaas 已提交
419
	for (i = 0; i < p->channel_count; i++)
420
		map |= 1 << p->channels[i];
L
Linus Torvalds 已提交
421

422 423
	flags = dma_flags(p->type, p->bus_master, p->transfer);
	pnp_register_dma_resource(dev, option, map, flags);
L
Linus Torvalds 已提交
424 425
}

426 427
static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
					    struct pnp_option *option,
428
					    struct acpi_resource_irq *p)
L
Linus Torvalds 已提交
429 430
{
	int i;
431 432
	pnp_irq_mask_t map;
	unsigned char flags;
B
Bjorn Helgaas 已提交
433

B
Bob Moore 已提交
434
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
435 436
		return;

437
	bitmap_zero(map.bits, PNP_IRQ_NR);
B
Bjorn Helgaas 已提交
438
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
439
		if (p->interrupts[i])
440
			__set_bit(p->interrupts[i], map.bits);
L
Linus Torvalds 已提交
441

442 443
	flags = irq_flags(p->triggering, p->polarity, p->sharable);
	pnp_register_irq_resource(dev, option, &map, flags);
L
Linus Torvalds 已提交
444 445
}

446 447
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
						struct pnp_option *option,
448
					struct acpi_resource_extended_irq *p)
L
Linus Torvalds 已提交
449 450
{
	int i;
451 452
	pnp_irq_mask_t map;
	unsigned char flags;
L
Linus Torvalds 已提交
453

B
Bob Moore 已提交
454
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
455 456
		return;

457
	bitmap_zero(map.bits, PNP_IRQ_NR);
B
Bjorn Helgaas 已提交
458
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
459
		if (p->interrupts[i])
460
			__set_bit(p->interrupts[i], map.bits);
L
Linus Torvalds 已提交
461

462 463
	flags = irq_flags(p->triggering, p->polarity, p->sharable);
	pnp_register_irq_resource(dev, option, &map, flags);
L
Linus Torvalds 已提交
464 465
}

466 467
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
					     struct pnp_option *option,
468
					     struct acpi_resource_io *io)
L
Linus Torvalds 已提交
469
{
470
	unsigned char flags = 0;
L
Linus Torvalds 已提交
471

B
Bob Moore 已提交
472
	if (io->address_length == 0)
L
Linus Torvalds 已提交
473
		return;
474 475 476 477 478

	if (io->io_decode == ACPI_DECODE_16)
		flags = IORESOURCE_IO_16BIT_ADDR;
	pnp_register_port_resource(dev, option, io->minimum, io->maximum,
				   io->alignment, io->address_length, flags);
L
Linus Torvalds 已提交
479 480
}

481 482
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
						   struct pnp_option *option,
483
					struct acpi_resource_fixed_io *io)
L
Linus Torvalds 已提交
484
{
B
Bob Moore 已提交
485
	if (io->address_length == 0)
L
Linus Torvalds 已提交
486
		return;
487 488 489

	pnp_register_port_resource(dev, option, io->address, io->address, 0,
				   io->address_length, IORESOURCE_IO_FIXED);
L
Linus Torvalds 已提交
490 491
}

492 493
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
					      struct pnp_option *option,
494
					      struct acpi_resource_memory24 *p)
L
Linus Torvalds 已提交
495
{
496
	unsigned char flags = 0;
L
Linus Torvalds 已提交
497

B
Bob Moore 已提交
498
	if (p->address_length == 0)
L
Linus Torvalds 已提交
499 500
		return;

501 502 503 504
	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
		flags = IORESOURCE_MEM_WRITEABLE;
	pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
				  p->alignment, p->address_length, flags);
L
Linus Torvalds 已提交
505 506
}

507 508
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
					      struct pnp_option *option,
509
					      struct acpi_resource_memory32 *p)
L
Linus Torvalds 已提交
510
{
511
	unsigned char flags = 0;
L
Linus Torvalds 已提交
512

B
Bob Moore 已提交
513
	if (p->address_length == 0)
L
Linus Torvalds 已提交
514 515
		return;

516 517 518 519
	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
		flags = IORESOURCE_MEM_WRITEABLE;
	pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
				  p->alignment, p->address_length, flags);
L
Linus Torvalds 已提交
520 521
}

522 523
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
						    struct pnp_option *option,
524
					struct acpi_resource_fixed_memory32 *p)
L
Linus Torvalds 已提交
525
{
526
	unsigned char flags = 0;
L
Linus Torvalds 已提交
527

B
Bob Moore 已提交
528
	if (p->address_length == 0)
L
Linus Torvalds 已提交
529 530
		return;

531 532 533 534
	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
		flags = IORESOURCE_MEM_WRITEABLE;
	pnp_register_mem_resource(dev, option, p->address, p->address,
				  0, p->address_length, flags);
L
Linus Torvalds 已提交
535 536
}

537 538
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
						struct pnp_option *option,
539
						struct acpi_resource *r)
540 541 542
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
543
	unsigned char flags = 0;
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 557 558 559 560 561 562 563
		if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
			flags = IORESOURCE_MEM_WRITEABLE;
		pnp_register_mem_resource(dev, option, p->minimum, p->minimum,
					  0, p->address_length, flags);
	} else if (p->resource_type == ACPI_IO_RANGE)
		pnp_register_port_resource(dev, option, p->minimum, p->minimum,
					   0, p->address_length,
					   IORESOURCE_IO_FIXED);
564 565
}

L
Linus Torvalds 已提交
566 567
struct acpipnp_parse_option_s {
	struct pnp_option *option;
M
Matthieu Castet 已提交
568
	struct pnp_option *option_independent;
L
Linus Torvalds 已提交
569 570 571
	struct pnp_dev *dev;
};

572 573
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
						  void *data)
L
Linus Torvalds 已提交
574 575
{
	int priority = 0;
576
	struct acpipnp_parse_option_s *parse_data = data;
L
Linus Torvalds 已提交
577 578 579
	struct pnp_dev *dev = parse_data->dev;
	struct pnp_option *option = parse_data->option;

580
	switch (res->type) {
B
Bjorn Helgaas 已提交
581
	case ACPI_RESOURCE_TYPE_IRQ:
582
		pnpacpi_parse_irq_option(dev, option, &res->data.irq);
B
Bjorn Helgaas 已提交
583
		break;
584

B
Bjorn Helgaas 已提交
585
	case ACPI_RESOURCE_TYPE_DMA:
586
		pnpacpi_parse_dma_option(dev, option, &res->data.dma);
B
Bjorn Helgaas 已提交
587
		break;
588

B
Bjorn Helgaas 已提交
589 590 591 592
	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 已提交
593
			break;
594

B
Bjorn Helgaas 已提交
595 596
		case ACPI_ACCEPTABLE_CONFIGURATION:
			priority = PNP_RES_PRIORITY_ACCEPTABLE;
M
Matthieu Castet 已提交
597
			break;
598

B
Bjorn Helgaas 已提交
599 600
		case ACPI_SUB_OPTIMAL_CONFIGURATION:
			priority = PNP_RES_PRIORITY_FUNCTIONAL;
601
			break;
B
Bjorn Helgaas 已提交
602 603
		default:
			priority = PNP_RES_PRIORITY_INVALID;
604
			break;
B
Bjorn Helgaas 已提交
605
		}
B
Bjorn Helgaas 已提交
606
		/* TBD: Consider performance/robustness bits */
B
Bjorn Helgaas 已提交
607 608 609 610 611
		option = pnp_register_dependent_option(dev, priority);
		if (!option)
			return AE_ERROR;
		parse_data->option = option;
		break;
612

B
Bjorn Helgaas 已提交
613 614 615
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		/*only one EndDependentFn is allowed */
		if (!parse_data->option_independent) {
616 617
			dev_warn(&dev->dev, "more than one EndDependentFn "
				 "in _PRS\n");
B
Bjorn Helgaas 已提交
618 619 620 621
			return AE_ERROR;
		}
		parse_data->option = parse_data->option_independent;
		parse_data->option_independent = NULL;
622
		dev_dbg(&dev->dev, "end dependent options\n");
B
Bjorn Helgaas 已提交
623
		break;
624

B
Bjorn Helgaas 已提交
625
	case ACPI_RESOURCE_TYPE_IO:
626
		pnpacpi_parse_port_option(dev, option, &res->data.io);
B
Bjorn Helgaas 已提交
627
		break;
628

B
Bjorn Helgaas 已提交
629
	case ACPI_RESOURCE_TYPE_FIXED_IO:
630 631
		pnpacpi_parse_fixed_port_option(dev, option,
					        &res->data.fixed_io);
B
Bjorn Helgaas 已提交
632
		break;
633

B
Bjorn Helgaas 已提交
634 635 636
	case ACPI_RESOURCE_TYPE_VENDOR:
	case ACPI_RESOURCE_TYPE_END_TAG:
		break;
637

B
Bjorn Helgaas 已提交
638
	case ACPI_RESOURCE_TYPE_MEMORY24:
639
		pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
B
Bjorn Helgaas 已提交
640
		break;
641

B
Bjorn Helgaas 已提交
642
	case ACPI_RESOURCE_TYPE_MEMORY32:
643
		pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
B
Bjorn Helgaas 已提交
644
		break;
645

B
Bjorn Helgaas 已提交
646
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
647
		pnpacpi_parse_fixed_mem32_option(dev, option,
B
Bjorn Helgaas 已提交
648 649
						 &res->data.fixed_memory32);
		break;
650

B
Bjorn Helgaas 已提交
651 652 653
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
654
		pnpacpi_parse_address_option(dev, option, res);
B
Bjorn Helgaas 已提交
655
		break;
656

B
Bjorn Helgaas 已提交
657 658 659 660
	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
661 662
		pnpacpi_parse_ext_irq_option(dev, option,
					     &res->data.extended_irq);
B
Bjorn Helgaas 已提交
663 664 665 666 667 668
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
		break;

	default:
669 670
		dev_warn(&dev->dev, "unknown resource type %d in _PRS\n",
			 res->type);
B
Bjorn Helgaas 已提交
671
		return AE_ERROR;
L
Linus Torvalds 已提交
672
	}
B
Bjorn Helgaas 已提交
673

L
Linus Torvalds 已提交
674 675 676
	return AE_OK;
}

677
int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
L
Linus Torvalds 已提交
678
{
679
	acpi_handle handle = dev->data;
L
Linus Torvalds 已提交
680 681 682
	acpi_status status;
	struct acpipnp_parse_option_s parse_data;

683 684
	dev_dbg(&dev->dev, "parse resource options\n");

L
Linus Torvalds 已提交
685 686
	parse_data.option = pnp_register_independent_option(dev);
	if (!parse_data.option)
687 688
		return -ENOMEM;

M
Matthieu Castet 已提交
689
	parse_data.option_independent = parse_data.option;
L
Linus Torvalds 已提交
690
	parse_data.dev = dev;
B
Bob Moore 已提交
691
	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
B
Bjorn Helgaas 已提交
692
				     pnpacpi_option_resource, &parse_data);
L
Linus Torvalds 已提交
693

694 695 696 697 698 699
	if (ACPI_FAILURE(status)) {
		if (status != AE_NOT_FOUND)
			dev_err(&dev->dev, "can't evaluate _PRS: %d", status);
		return -EPERM;
	}
	return 0;
L
Linus Torvalds 已提交
700 701
}

702
static int pnpacpi_supported_resource(struct acpi_resource *res)
L
Linus Torvalds 已提交
703
{
704
	switch (res->type) {
B
Bob Moore 已提交
705 706 707 708 709 710 711 712 713 714
	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:
715
	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
716
		return 1;
L
Linus Torvalds 已提交
717
	}
718 719 720 721 722 723 724
	return 0;
}

/*
 * Set resource
 */
static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
725
					   void *data)
726
{
727
	int *res_cnt = data;
728 729 730

	if (pnpacpi_supported_resource(res))
		(*res_cnt)++;
L
Linus Torvalds 已提交
731 732 733
	return AE_OK;
}

B
Bjorn Helgaas 已提交
734
static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
L
Linus Torvalds 已提交
735
{
736
	struct acpi_resource **resource = data;
737 738

	if (pnpacpi_supported_resource(res)) {
739
		(*resource)->type = res->type;
740
		(*resource)->length = sizeof(struct acpi_resource);
741 742 743
		if (res->type == ACPI_RESOURCE_TYPE_IRQ)
			(*resource)->data.irq.descriptor_length =
					res->data.irq.descriptor_length;
L
Linus Torvalds 已提交
744 745 746 747 748 749
		(*resource)++;
	}

	return AE_OK;
}

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

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

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

	return 0;
}

785 786
static void pnpacpi_encode_irq(struct pnp_dev *dev,
			       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
787
			       struct resource *p)
L
Linus Torvalds 已提交
788
{
789
	struct acpi_resource_irq *irq = &resource->data.irq;
790
	int triggering, polarity, shareable;
B
Bjorn Helgaas 已提交
791

792 793 794 795 796 797 798
	if (!pnp_resource_enabled(p)) {
		irq->interrupt_count = 0;
		dev_dbg(&dev->dev, "  encode irq (%s)\n",
			p ? "disabled" : "missing");
		return;
	}

799
	decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
800 801
	irq->triggering = triggering;
	irq->polarity = polarity;
802
	irq->sharable = shareable;
803 804
	irq->interrupt_count = 1;
	irq->interrupts[0] = p->start;
805

806 807
	dev_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
		(int) p->start,
808 809
		triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
		polarity == ACPI_ACTIVE_LOW ? "low" : "high",
810 811
		irq->sharable == ACPI_SHARED ? "shared" : "exclusive",
		irq->descriptor_length);
L
Linus Torvalds 已提交
812 813
}

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

821 822 823 824 825 826 827
	if (!pnp_resource_enabled(p)) {
		extended_irq->interrupt_count = 0;
		dev_dbg(&dev->dev, "  encode extended irq (%s)\n",
			p ? "disabled" : "missing");
		return;
	}

828
	decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
829 830 831
	extended_irq->producer_consumer = ACPI_CONSUMER;
	extended_irq->triggering = triggering;
	extended_irq->polarity = polarity;
832
	extended_irq->sharable = shareable;
833 834
	extended_irq->interrupt_count = 1;
	extended_irq->interrupts[0] = p->start;
835 836 837 838 839

	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 已提交
840 841
}

842 843
static void pnpacpi_encode_dma(struct pnp_dev *dev,
			       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
844
			       struct resource *p)
L
Linus Torvalds 已提交
845
{
846 847
	struct acpi_resource_dma *dma = &resource->data.dma;

848 849 850 851 852 853 854
	if (!pnp_resource_enabled(p)) {
		dma->channel_count = 0;
		dev_dbg(&dev->dev, "  encode dma (%s)\n",
			p ? "disabled" : "missing");
		return;
	}

L
Linus Torvalds 已提交
855
	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
856
	switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
B
Bjorn Helgaas 已提交
857
	case IORESOURCE_DMA_TYPEA:
858
		dma->type = ACPI_TYPE_A;
B
Bjorn Helgaas 已提交
859 860
		break;
	case IORESOURCE_DMA_TYPEB:
861
		dma->type = ACPI_TYPE_B;
B
Bjorn Helgaas 已提交
862 863
		break;
	case IORESOURCE_DMA_TYPEF:
864
		dma->type = ACPI_TYPE_F;
B
Bjorn Helgaas 已提交
865 866
		break;
	default:
867
		dma->type = ACPI_COMPATIBILITY;
868 869 870
	}

	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
B
Bjorn Helgaas 已提交
871
	case IORESOURCE_DMA_8BIT:
872
		dma->transfer = ACPI_TRANSFER_8;
B
Bjorn Helgaas 已提交
873 874
		break;
	case IORESOURCE_DMA_8AND16BIT:
875
		dma->transfer = ACPI_TRANSFER_8_16;
B
Bjorn Helgaas 已提交
876 877
		break;
	default:
878
		dma->transfer = ACPI_TRANSFER_16;
879 880
	}

881 882 883
	dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
	dma->channel_count = 1;
	dma->channels[0] = p->start;
884 885 886 887

	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 已提交
888 889
}

890 891
static void pnpacpi_encode_io(struct pnp_dev *dev,
			      struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
892
			      struct resource *p)
L
Linus Torvalds 已提交
893
{
894 895
	struct acpi_resource_io *io = &resource->data.io;

896 897
	if (pnp_resource_enabled(p)) {
		/* Note: pnp_assign_port copies pnp_port->flags into p->flags */
898
		io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
899 900 901 902 903 904 905 906 907
		    ACPI_DECODE_16 : ACPI_DECODE_10;
		io->minimum = p->start;
		io->maximum = p->end;
		io->alignment = 0;	/* Correct? */
		io->address_length = p->end - p->start + 1;
	} else {
		io->minimum = 0;
		io->address_length = 0;
	}
908

909 910
	dev_dbg(&dev->dev, "  encode io %#x-%#x decode %#x\n", io->minimum,
		io->minimum + io->address_length - 1, io->io_decode);
L
Linus Torvalds 已提交
911 912
}

913 914
static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
				    struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
915
				    struct resource *p)
L
Linus Torvalds 已提交
916
{
917 918
	struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;

919 920 921 922 923 924 925
	if (pnp_resource_enabled(p)) {
		fixed_io->address = p->start;
		fixed_io->address_length = p->end - p->start + 1;
	} else {
		fixed_io->address = 0;
		fixed_io->address_length = 0;
	}
926

927 928
	dev_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
		fixed_io->address + fixed_io->address_length - 1);
L
Linus Torvalds 已提交
929 930
}

931 932
static void pnpacpi_encode_mem24(struct pnp_dev *dev,
				 struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
933
				 struct resource *p)
L
Linus Torvalds 已提交
934
{
935 936
	struct acpi_resource_memory24 *memory24 = &resource->data.memory24;

937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952
	if (pnp_resource_enabled(p)) {
		/* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
		memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
		    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
		memory24->minimum = p->start;
		memory24->maximum = p->end;
		memory24->alignment = 0;
		memory24->address_length = p->end - p->start + 1;
	} else {
		memory24->minimum = 0;
		memory24->address_length = 0;
	}

	dev_dbg(&dev->dev, "  encode mem24 %#x-%#x write_protect %#x\n",
		memory24->minimum,
		memory24->minimum + memory24->address_length - 1,
953
		memory24->write_protect);
L
Linus Torvalds 已提交
954 955
}

956 957
static void pnpacpi_encode_mem32(struct pnp_dev *dev,
				 struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
958
				 struct resource *p)
L
Linus Torvalds 已提交
959
{
960 961
	struct acpi_resource_memory32 *memory32 = &resource->data.memory32;

962 963 964 965 966 967 968 969 970 971 972
	if (pnp_resource_enabled(p)) {
		memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
		    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
		memory32->minimum = p->start;
		memory32->maximum = p->end;
		memory32->alignment = 0;
		memory32->address_length = p->end - p->start + 1;
	} else {
		memory32->minimum = 0;
		memory32->alignment = 0;
	}
973

974 975 976
	dev_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
		memory32->minimum,
		memory32->minimum + memory32->address_length - 1,
977
		memory32->write_protect);
L
Linus Torvalds 已提交
978 979
}

980 981
static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
				       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
982
				       struct resource *p)
L
Linus Torvalds 已提交
983
{
984 985
	struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;

986 987 988 989 990 991 992 993 994 995
	if (pnp_resource_enabled(p)) {
		fixed_memory32->write_protect =
		    p->flags & IORESOURCE_MEM_WRITEABLE ?
		    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
		fixed_memory32->address = p->start;
		fixed_memory32->address_length = p->end - p->start + 1;
	} else {
		fixed_memory32->address = 0;
		fixed_memory32->address_length = 0;
	}
996

997 998 999
	dev_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
		fixed_memory32->address,
		fixed_memory32->address + fixed_memory32->address_length - 1,
1000
		fixed_memory32->write_protect);
L
Linus Torvalds 已提交
1001 1002
}

1003
int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
1004 1005 1006
{
	int i = 0;
	/* pnpacpi_build_resource_template allocates extra mem */
B
Bjorn Helgaas 已提交
1007
	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
1008
	struct acpi_resource *resource = buffer->pointer;
L
Linus Torvalds 已提交
1009 1010
	int port = 0, irq = 0, dma = 0, mem = 0;

1011
	dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
L
Linus Torvalds 已提交
1012
	while (i < res_cnt) {
B
Bjorn Helgaas 已提交
1013
		switch (resource->type) {
B
Bob Moore 已提交
1014
		case ACPI_RESOURCE_TYPE_IRQ:
1015
			pnpacpi_encode_irq(dev, resource,
1016
			       pnp_get_resource(dev, IORESOURCE_IRQ, irq));
L
Linus Torvalds 已提交
1017 1018 1019
			irq++;
			break;

B
Bob Moore 已提交
1020
		case ACPI_RESOURCE_TYPE_DMA:
1021
			pnpacpi_encode_dma(dev, resource,
1022
				pnp_get_resource(dev, IORESOURCE_DMA, dma));
B
Bjorn Helgaas 已提交
1023
			dma++;
L
Linus Torvalds 已提交
1024
			break;
B
Bob Moore 已提交
1025
		case ACPI_RESOURCE_TYPE_IO:
1026
			pnpacpi_encode_io(dev, resource,
1027
				pnp_get_resource(dev, IORESOURCE_IO, port));
B
Bjorn Helgaas 已提交
1028
			port++;
L
Linus Torvalds 已提交
1029
			break;
B
Bob Moore 已提交
1030
		case ACPI_RESOURCE_TYPE_FIXED_IO:
1031
			pnpacpi_encode_fixed_io(dev, resource,
1032
				pnp_get_resource(dev, IORESOURCE_IO, port));
B
Bjorn Helgaas 已提交
1033
			port++;
L
Linus Torvalds 已提交
1034
			break;
B
Bob Moore 已提交
1035
		case ACPI_RESOURCE_TYPE_MEMORY24:
1036
			pnpacpi_encode_mem24(dev, resource,
1037
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
B
Bjorn Helgaas 已提交
1038
			mem++;
L
Linus Torvalds 已提交
1039
			break;
B
Bob Moore 已提交
1040
		case ACPI_RESOURCE_TYPE_MEMORY32:
1041
			pnpacpi_encode_mem32(dev, resource,
1042
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
B
Bjorn Helgaas 已提交
1043
			mem++;
L
Linus Torvalds 已提交
1044
			break;
B
Bob Moore 已提交
1045
		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
1046
			pnpacpi_encode_fixed_mem32(dev, resource,
1047
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
B
Bjorn Helgaas 已提交
1048
			mem++;
L
Linus Torvalds 已提交
1049
			break;
1050
		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
1051
			pnpacpi_encode_ext_irq(dev, resource,
1052
				pnp_get_resource(dev, IORESOURCE_IRQ, irq));
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
			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 已提交
1064
		default:	/* other type */
1065 1066
			dev_warn(&dev->dev, "can't encode unknown resource "
				 "type %d\n", resource->type);
L
Linus Torvalds 已提交
1067 1068
			return -EINVAL;
		}
B
Bjorn Helgaas 已提交
1069 1070
		resource++;
		i++;
L
Linus Torvalds 已提交
1071 1072 1073
	}
	return 0;
}