rsparser.c 28.0 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
static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
410
					    unsigned int option_flags,
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
	flags = dma_flags(p->type, p->bus_master, p->transfer);
423
	pnp_register_dma_resource(dev, option_flags, map, flags);
L
Linus Torvalds 已提交
424 425
}

426
static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
427
					    unsigned int option_flags,
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
	flags = irq_flags(p->triggering, p->polarity, p->sharable);
443
	pnp_register_irq_resource(dev, option_flags, &map, flags);
L
Linus Torvalds 已提交
444 445
}

446
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
447
					unsigned int option_flags,
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);
458 459 460 461 462 463 464 465 466 467
	for (i = 0; i < p->interrupt_count; i++) {
		if (p->interrupts[i]) {
			if (p->interrupts[i] < PNP_IRQ_NR)
				__set_bit(p->interrupts[i], map.bits);
			else
				dev_err(&dev->dev, "ignoring IRQ %d option "
					"(too large for %d entry bitmap)\n",
					p->interrupts[i], PNP_IRQ_NR);
		}
	}
L
Linus Torvalds 已提交
468

469
	flags = irq_flags(p->triggering, p->polarity, p->sharable);
470
	pnp_register_irq_resource(dev, option_flags, &map, flags);
L
Linus Torvalds 已提交
471 472
}

473
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
474
					     unsigned int option_flags,
475
					     struct acpi_resource_io *io)
L
Linus Torvalds 已提交
476
{
477
	unsigned char flags = 0;
L
Linus Torvalds 已提交
478

B
Bob Moore 已提交
479
	if (io->address_length == 0)
L
Linus Torvalds 已提交
480
		return;
481 482 483

	if (io->io_decode == ACPI_DECODE_16)
		flags = IORESOURCE_IO_16BIT_ADDR;
484
	pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
485
				   io->alignment, io->address_length, flags);
L
Linus Torvalds 已提交
486 487
}

488
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
489
					unsigned int option_flags,
490
					struct acpi_resource_fixed_io *io)
L
Linus Torvalds 已提交
491
{
B
Bob Moore 已提交
492
	if (io->address_length == 0)
L
Linus Torvalds 已提交
493
		return;
494

495 496
	pnp_register_port_resource(dev, option_flags, io->address, io->address,
				   0, io->address_length, IORESOURCE_IO_FIXED);
L
Linus Torvalds 已提交
497 498
}

499
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
500
					      unsigned int option_flags,
501
					      struct acpi_resource_memory24 *p)
L
Linus Torvalds 已提交
502
{
503
	unsigned char flags = 0;
L
Linus Torvalds 已提交
504

B
Bob Moore 已提交
505
	if (p->address_length == 0)
L
Linus Torvalds 已提交
506 507
		return;

508 509
	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
		flags = IORESOURCE_MEM_WRITEABLE;
510
	pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
511
				  p->alignment, p->address_length, flags);
L
Linus Torvalds 已提交
512 513
}

514
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
515
					      unsigned int option_flags,
516
					      struct acpi_resource_memory32 *p)
L
Linus Torvalds 已提交
517
{
518
	unsigned char flags = 0;
L
Linus Torvalds 已提交
519

B
Bob Moore 已提交
520
	if (p->address_length == 0)
L
Linus Torvalds 已提交
521 522
		return;

523 524
	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
		flags = IORESOURCE_MEM_WRITEABLE;
525
	pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
526
				  p->alignment, p->address_length, flags);
L
Linus Torvalds 已提交
527 528
}

529
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
530
					unsigned int option_flags,
531
					struct acpi_resource_fixed_memory32 *p)
L
Linus Torvalds 已提交
532
{
533
	unsigned char flags = 0;
L
Linus Torvalds 已提交
534

B
Bob Moore 已提交
535
	if (p->address_length == 0)
L
Linus Torvalds 已提交
536 537
		return;

538 539
	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
		flags = IORESOURCE_MEM_WRITEABLE;
540
	pnp_register_mem_resource(dev, option_flags, p->address, p->address,
541
				  0, p->address_length, flags);
L
Linus Torvalds 已提交
542 543
}

544
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
545
						unsigned int option_flags,
546
						struct acpi_resource *r)
547 548 549
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
550
	unsigned char flags = 0;
551 552 553

	status = acpi_resource_to_address64(r, p);
	if (!ACPI_SUCCESS(status)) {
B
Bjorn Helgaas 已提交
554 555
		pnp_warn("PnPACPI: failed to convert resource type %d",
			 r->type);
556 557 558 559 560 561 562
		return;
	}

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

	if (p->resource_type == ACPI_MEMORY_RANGE) {
563 564
		if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
			flags = IORESOURCE_MEM_WRITEABLE;
565 566 567
		pnp_register_mem_resource(dev, option_flags, p->minimum,
					  p->minimum, 0, p->address_length,
					  flags);
568
	} else if (p->resource_type == ACPI_IO_RANGE)
569 570
		pnp_register_port_resource(dev, option_flags, p->minimum,
					   p->minimum, 0, p->address_length,
571
					   IORESOURCE_IO_FIXED);
572 573
}

L
Linus Torvalds 已提交
574 575
struct acpipnp_parse_option_s {
	struct pnp_dev *dev;
576
	unsigned int option_flags;
L
Linus Torvalds 已提交
577 578
};

579 580
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
						  void *data)
L
Linus Torvalds 已提交
581
{
582
	int priority;
583
	struct acpipnp_parse_option_s *parse_data = data;
L
Linus Torvalds 已提交
584
	struct pnp_dev *dev = parse_data->dev;
585
	unsigned int option_flags = parse_data->option_flags;
L
Linus Torvalds 已提交
586

587
	switch (res->type) {
B
Bjorn Helgaas 已提交
588
	case ACPI_RESOURCE_TYPE_IRQ:
589
		pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq);
B
Bjorn Helgaas 已提交
590
		break;
591

B
Bjorn Helgaas 已提交
592
	case ACPI_RESOURCE_TYPE_DMA:
593
		pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma);
B
Bjorn Helgaas 已提交
594
		break;
595

B
Bjorn Helgaas 已提交
596 597 598 599
	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 已提交
600
			break;
601

B
Bjorn Helgaas 已提交
602 603
		case ACPI_ACCEPTABLE_CONFIGURATION:
			priority = PNP_RES_PRIORITY_ACCEPTABLE;
M
Matthieu Castet 已提交
604
			break;
605

B
Bjorn Helgaas 已提交
606 607
		case ACPI_SUB_OPTIMAL_CONFIGURATION:
			priority = PNP_RES_PRIORITY_FUNCTIONAL;
608
			break;
B
Bjorn Helgaas 已提交
609 610
		default:
			priority = PNP_RES_PRIORITY_INVALID;
611
			break;
B
Bjorn Helgaas 已提交
612
		}
613
		parse_data->option_flags = pnp_new_dependent_set(dev, priority);
B
Bjorn Helgaas 已提交
614
		break;
615

B
Bjorn Helgaas 已提交
616
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
617
		parse_data->option_flags = 0;
B
Bjorn Helgaas 已提交
618
		break;
619

B
Bjorn Helgaas 已提交
620
	case ACPI_RESOURCE_TYPE_IO:
621
		pnpacpi_parse_port_option(dev, option_flags, &res->data.io);
B
Bjorn Helgaas 已提交
622
		break;
623

B
Bjorn Helgaas 已提交
624
	case ACPI_RESOURCE_TYPE_FIXED_IO:
625
		pnpacpi_parse_fixed_port_option(dev, option_flags,
626
					        &res->data.fixed_io);
B
Bjorn Helgaas 已提交
627
		break;
628

B
Bjorn Helgaas 已提交
629 630 631
	case ACPI_RESOURCE_TYPE_VENDOR:
	case ACPI_RESOURCE_TYPE_END_TAG:
		break;
632

B
Bjorn Helgaas 已提交
633
	case ACPI_RESOURCE_TYPE_MEMORY24:
634 635
		pnpacpi_parse_mem24_option(dev, option_flags,
					   &res->data.memory24);
B
Bjorn Helgaas 已提交
636
		break;
637

B
Bjorn Helgaas 已提交
638
	case ACPI_RESOURCE_TYPE_MEMORY32:
639 640
		pnpacpi_parse_mem32_option(dev, option_flags,
					   &res->data.memory32);
B
Bjorn Helgaas 已提交
641
		break;
642

B
Bjorn Helgaas 已提交
643
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
644
		pnpacpi_parse_fixed_mem32_option(dev, option_flags,
B
Bjorn Helgaas 已提交
645 646
						 &res->data.fixed_memory32);
		break;
647

B
Bjorn Helgaas 已提交
648 649 650
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
651
		pnpacpi_parse_address_option(dev, option_flags, res);
B
Bjorn Helgaas 已提交
652
		break;
653

B
Bjorn Helgaas 已提交
654 655 656 657
	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
658
		pnpacpi_parse_ext_irq_option(dev, option_flags,
659
					     &res->data.extended_irq);
B
Bjorn Helgaas 已提交
660 661 662 663 664 665
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
		break;

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

L
Linus Torvalds 已提交
671 672 673
	return AE_OK;
}

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

680 681
	dev_dbg(&dev->dev, "parse resource options\n");

L
Linus Torvalds 已提交
682
	parse_data.dev = dev;
683 684
	parse_data.option_flags = 0;

B
Bob Moore 已提交
685
	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
B
Bjorn Helgaas 已提交
686
				     pnpacpi_option_resource, &parse_data);
L
Linus Torvalds 已提交
687

688 689 690 691 692 693
	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 已提交
694 695
}

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

/*
 * Set resource
 */
static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
719
					   void *data)
720
{
721
	int *res_cnt = data;
722 723 724

	if (pnpacpi_supported_resource(res))
		(*res_cnt)++;
L
Linus Torvalds 已提交
725 726 727
	return AE_OK;
}

B
Bjorn Helgaas 已提交
728
static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
L
Linus Torvalds 已提交
729
{
730
	struct acpi_resource **resource = data;
731 732

	if (pnpacpi_supported_resource(res)) {
733
		(*resource)->type = res->type;
734
		(*resource)->length = sizeof(struct acpi_resource);
735 736 737
		if (res->type == ACPI_RESOURCE_TYPE_IRQ)
			(*resource)->data.irq.descriptor_length =
					res->data.irq.descriptor_length;
L
Linus Torvalds 已提交
738 739 740 741 742 743
		(*resource)++;
	}

	return AE_OK;
}

744
int pnpacpi_build_resource_template(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
745
				    struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
746
{
747
	acpi_handle handle = dev->data;
L
Linus Torvalds 已提交
748 749 750 751
	struct acpi_resource *resource;
	int res_cnt = 0;
	acpi_status status;

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

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

	return 0;
}

779 780
static void pnpacpi_encode_irq(struct pnp_dev *dev,
			       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
781
			       struct resource *p)
L
Linus Torvalds 已提交
782
{
783
	struct acpi_resource_irq *irq = &resource->data.irq;
784
	int triggering, polarity, shareable;
B
Bjorn Helgaas 已提交
785

786 787 788 789 790 791 792
	if (!pnp_resource_enabled(p)) {
		irq->interrupt_count = 0;
		dev_dbg(&dev->dev, "  encode irq (%s)\n",
			p ? "disabled" : "missing");
		return;
	}

793
	decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
794 795
	irq->triggering = triggering;
	irq->polarity = polarity;
796
	irq->sharable = shareable;
797 798
	irq->interrupt_count = 1;
	irq->interrupts[0] = p->start;
799

800 801
	dev_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
		(int) p->start,
802 803
		triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
		polarity == ACPI_ACTIVE_LOW ? "low" : "high",
804 805
		irq->sharable == ACPI_SHARED ? "shared" : "exclusive",
		irq->descriptor_length);
L
Linus Torvalds 已提交
806 807
}

808 809
static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
				   struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
810
				   struct resource *p)
L
Linus Torvalds 已提交
811
{
812
	struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
813
	int triggering, polarity, shareable;
B
Bjorn Helgaas 已提交
814

815 816 817 818 819 820 821
	if (!pnp_resource_enabled(p)) {
		extended_irq->interrupt_count = 0;
		dev_dbg(&dev->dev, "  encode extended irq (%s)\n",
			p ? "disabled" : "missing");
		return;
	}

822
	decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
823 824 825
	extended_irq->producer_consumer = ACPI_CONSUMER;
	extended_irq->triggering = triggering;
	extended_irq->polarity = polarity;
826
	extended_irq->sharable = shareable;
827 828
	extended_irq->interrupt_count = 1;
	extended_irq->interrupts[0] = p->start;
829 830 831 832 833

	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 已提交
834 835
}

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

842 843 844 845 846 847 848
	if (!pnp_resource_enabled(p)) {
		dma->channel_count = 0;
		dev_dbg(&dev->dev, "  encode dma (%s)\n",
			p ? "disabled" : "missing");
		return;
	}

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

	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
B
Bjorn Helgaas 已提交
865
	case IORESOURCE_DMA_8BIT:
866
		dma->transfer = ACPI_TRANSFER_8;
B
Bjorn Helgaas 已提交
867 868
		break;
	case IORESOURCE_DMA_8AND16BIT:
869
		dma->transfer = ACPI_TRANSFER_8_16;
B
Bjorn Helgaas 已提交
870 871
		break;
	default:
872
		dma->transfer = ACPI_TRANSFER_16;
873 874
	}

875 876 877
	dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
	dma->channel_count = 1;
	dma->channels[0] = p->start;
878 879 880 881

	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 已提交
882 883
}

884 885
static void pnpacpi_encode_io(struct pnp_dev *dev,
			      struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
886
			      struct resource *p)
L
Linus Torvalds 已提交
887
{
888 889
	struct acpi_resource_io *io = &resource->data.io;

890 891
	if (pnp_resource_enabled(p)) {
		/* Note: pnp_assign_port copies pnp_port->flags into p->flags */
892
		io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
893 894 895 896 897 898 899 900 901
		    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;
	}
902

903 904
	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 已提交
905 906
}

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

913 914 915 916 917 918 919
	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;
	}
920

921 922
	dev_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
		fixed_io->address + fixed_io->address_length - 1);
L
Linus Torvalds 已提交
923 924
}

925 926
static void pnpacpi_encode_mem24(struct pnp_dev *dev,
				 struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
927
				 struct resource *p)
L
Linus Torvalds 已提交
928
{
929 930
	struct acpi_resource_memory24 *memory24 = &resource->data.memory24;

931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946
	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,
947
		memory24->write_protect);
L
Linus Torvalds 已提交
948 949
}

950 951
static void pnpacpi_encode_mem32(struct pnp_dev *dev,
				 struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
952
				 struct resource *p)
L
Linus Torvalds 已提交
953
{
954 955
	struct acpi_resource_memory32 *memory32 = &resource->data.memory32;

956 957 958 959 960 961 962 963 964 965 966
	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;
	}
967

968 969 970
	dev_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
		memory32->minimum,
		memory32->minimum + memory32->address_length - 1,
971
		memory32->write_protect);
L
Linus Torvalds 已提交
972 973
}

974 975
static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
				       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
976
				       struct resource *p)
L
Linus Torvalds 已提交
977
{
978 979
	struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;

980 981 982 983 984 985 986 987 988 989
	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;
	}
990

991 992 993
	dev_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
		fixed_memory32->address,
		fixed_memory32->address + fixed_memory32->address_length - 1,
994
		fixed_memory32->write_protect);
L
Linus Torvalds 已提交
995 996
}

997
int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
998 999 1000
{
	int i = 0;
	/* pnpacpi_build_resource_template allocates extra mem */
B
Bjorn Helgaas 已提交
1001
	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
1002
	struct acpi_resource *resource = buffer->pointer;
L
Linus Torvalds 已提交
1003 1004
	int port = 0, irq = 0, dma = 0, mem = 0;

1005
	dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
L
Linus Torvalds 已提交
1006
	while (i < res_cnt) {
B
Bjorn Helgaas 已提交
1007
		switch (resource->type) {
B
Bob Moore 已提交
1008
		case ACPI_RESOURCE_TYPE_IRQ:
1009
			pnpacpi_encode_irq(dev, resource,
1010
			       pnp_get_resource(dev, IORESOURCE_IRQ, irq));
L
Linus Torvalds 已提交
1011 1012 1013
			irq++;
			break;

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