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,
176
						u64 start, u64 len,
B
Bjorn Helgaas 已提交
177
						int write_protect)
L
Linus Torvalds 已提交
178
{
179 180 181 182 183 184 185 186 187
	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 已提交
188 189
}

190
static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
191
						  struct acpi_resource *res)
192 193 194 195 196 197
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;

	status = acpi_resource_to_address64(res, p);
	if (!ACPI_SUCCESS(status)) {
198
		dev_warn(&dev->dev, "failed to convert resource type %d\n",
B
Bjorn Helgaas 已提交
199
			 res->type);
200 201 202
		return;
	}

203 204 205
	if (p->producer_consumer == ACPI_PRODUCER)
		return;

206
	if (p->resource_type == ACPI_MEMORY_RANGE)
207
		pnpacpi_parse_allocated_memresource(dev,
B
Bjorn Helgaas 已提交
208 209
			p->minimum, p->address_length,
			p->info.mem.write_protect);
210
	else if (p->resource_type == ACPI_IO_RANGE)
211
		pnpacpi_parse_allocated_ioresource(dev,
B
Bjorn Helgaas 已提交
212 213 214
			p->minimum, p->address_length,
			p->granularity == 0xfff ? ACPI_DECODE_10 :
				ACPI_DECODE_16);
215
}
L
Linus Torvalds 已提交
216 217

static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
218
					      void *data)
L
Linus Torvalds 已提交
219
{
220
	struct pnp_dev *dev = data;
221 222 223 224 225 226 227 228
	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;
229
	int i, flags;
L
Linus Torvalds 已提交
230

231
	switch (res->type) {
B
Bob Moore 已提交
232
	case ACPI_RESOURCE_TYPE_IRQ:
233 234 235 236
		/*
		 * Per spec, only one interrupt per descriptor is allowed in
		 * _CRS, but some firmware violates this, so parse them all.
		 */
237 238
		irq = &res->data.irq;
		for (i = 0; i < irq->interrupt_count; i++) {
239
			pnpacpi_parse_allocated_irqresource(dev,
240 241 242 243
				irq->interrupts[i],
				irq->triggering,
				irq->polarity,
				irq->sharable);
L
Linus Torvalds 已提交
244 245 246
		}
		break;

B
Bob Moore 已提交
247
	case ACPI_RESOURCE_TYPE_DMA:
248
		dma = &res->data.dma;
249 250 251 252 253 254 255
		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 已提交
256
		break;
257

B
Bob Moore 已提交
258
	case ACPI_RESOURCE_TYPE_IO:
259
		io = &res->data.io;
260
		pnpacpi_parse_allocated_ioresource(dev,
261 262 263
			io->minimum,
			io->address_length,
			io->io_decode);
L
Linus Torvalds 已提交
264
		break;
265 266 267 268 269

	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		break;

B
Bob Moore 已提交
270
	case ACPI_RESOURCE_TYPE_FIXED_IO:
271
		fixed_io = &res->data.fixed_io;
272
		pnpacpi_parse_allocated_ioresource(dev,
273 274
			fixed_io->address,
			fixed_io->address_length,
B
Bjorn Helgaas 已提交
275
			ACPI_DECODE_10);
L
Linus Torvalds 已提交
276
		break;
277 278 279 280 281 282 283

	case ACPI_RESOURCE_TYPE_VENDOR:
		break;

	case ACPI_RESOURCE_TYPE_END_TAG:
		break;

B
Bob Moore 已提交
284
	case ACPI_RESOURCE_TYPE_MEMORY24:
285
		memory24 = &res->data.memory24;
286
		pnpacpi_parse_allocated_memresource(dev,
287 288 289
			memory24->minimum,
			memory24->address_length,
			memory24->write_protect);
L
Linus Torvalds 已提交
290
		break;
B
Bob Moore 已提交
291
	case ACPI_RESOURCE_TYPE_MEMORY32:
292
		memory32 = &res->data.memory32;
293
		pnpacpi_parse_allocated_memresource(dev,
294 295 296
			memory32->minimum,
			memory32->address_length,
			memory32->write_protect);
L
Linus Torvalds 已提交
297
		break;
B
Bob Moore 已提交
298
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
299
		fixed_memory32 = &res->data.fixed_memory32;
300
		pnpacpi_parse_allocated_memresource(dev,
301 302 303
			fixed_memory32->address,
			fixed_memory32->address_length,
			fixed_memory32->write_protect);
L
Linus Torvalds 已提交
304
		break;
B
Bob Moore 已提交
305 306 307
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
308
		pnpacpi_parse_allocated_address_space(dev, res);
L
Linus Torvalds 已提交
309
		break;
310 311

	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
312 313
		if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
			return AE_OK;
314 315 316
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
317 318
		extended_irq = &res->data.extended_irq;
		if (extended_irq->producer_consumer == ACPI_PRODUCER)
319 320
			return AE_OK;

321
		for (i = 0; i < extended_irq->interrupt_count; i++) {
322
			pnpacpi_parse_allocated_irqresource(dev,
323 324 325 326
				extended_irq->interrupts[i],
				extended_irq->triggering,
				extended_irq->polarity,
				extended_irq->sharable);
327 328 329 330
		}
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
L
Linus Torvalds 已提交
331
		break;
332

L
Linus Torvalds 已提交
333
	default:
334 335
		dev_warn(&dev->dev, "unknown resource type %d in _CRS\n",
			 res->type);
L
Linus Torvalds 已提交
336 337
		return AE_ERROR;
	}
B
Bjorn Helgaas 已提交
338

L
Linus Torvalds 已提交
339 340 341
	return AE_OK;
}

342
int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
L
Linus Torvalds 已提交
343
{
344
	acpi_handle handle = dev->data;
345
	acpi_status status;
346

347 348
	dev_dbg(&dev->dev, "parse allocated resources\n");

349
	pnp_init_resources(dev);
L
Linus Torvalds 已提交
350

351 352 353 354 355 356 357 358 359
	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 已提交
360 361
}

362 363
static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
					    struct pnp_option *option,
364
					    struct acpi_resource_dma *p)
L
Linus Torvalds 已提交
365 366
{
	int i;
B
Bjorn Helgaas 已提交
367
	struct pnp_dma *dma;
L
Linus Torvalds 已提交
368

B
Bob Moore 已提交
369
	if (p->channel_count == 0)
L
Linus Torvalds 已提交
370
		return;
371
	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
L
Linus Torvalds 已提交
372 373 374
	if (!dma)
		return;

B
Bjorn Helgaas 已提交
375
	for (i = 0; i < p->channel_count; i++)
L
Linus Torvalds 已提交
376
		dma->map |= 1 << p->channels[i];
377 378

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

380
	pnp_register_dma_resource(dev, option, dma);
L
Linus Torvalds 已提交
381 382
}

383 384
static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
					    struct pnp_option *option,
385
					    struct acpi_resource_irq *p)
L
Linus Torvalds 已提交
386 387
{
	int i;
B
Bjorn Helgaas 已提交
388 389
	struct pnp_irq *irq;

B
Bob Moore 已提交
390
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
391
		return;
392
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
393 394 395
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
396
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
397 398
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
399
	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
L
Linus Torvalds 已提交
400

401
	pnp_register_irq_resource(dev, option, irq);
L
Linus Torvalds 已提交
402 403
}

404 405
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
						struct pnp_option *option,
406
					struct acpi_resource_extended_irq *p)
L
Linus Torvalds 已提交
407 408
{
	int i;
B
Bjorn Helgaas 已提交
409
	struct pnp_irq *irq;
L
Linus Torvalds 已提交
410

B
Bob Moore 已提交
411
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
412
		return;
413
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
414 415 416
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
417
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
418 419
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
420
	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
L
Linus Torvalds 已提交
421

422
	pnp_register_irq_resource(dev, option, irq);
L
Linus Torvalds 已提交
423 424
}

425 426
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
					     struct pnp_option *option,
427
					     struct acpi_resource_io *io)
L
Linus Torvalds 已提交
428
{
B
Bjorn Helgaas 已提交
429
	struct pnp_port *port;
L
Linus Torvalds 已提交
430

B
Bob Moore 已提交
431
	if (io->address_length == 0)
L
Linus Torvalds 已提交
432
		return;
433
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
434 435
	if (!port)
		return;
B
Bob Moore 已提交
436 437
	port->min = io->minimum;
	port->max = io->maximum;
L
Linus Torvalds 已提交
438
	port->align = io->alignment;
B
Bob Moore 已提交
439 440
	port->size = io->address_length;
	port->flags = ACPI_DECODE_16 == io->io_decode ?
B
Bjorn Helgaas 已提交
441
	    PNP_PORT_FLAG_16BITADDR : 0;
442
	pnp_register_port_resource(dev, option, port);
L
Linus Torvalds 已提交
443 444
}

445 446
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
						   struct pnp_option *option,
447
					struct acpi_resource_fixed_io *io)
L
Linus Torvalds 已提交
448
{
B
Bjorn Helgaas 已提交
449
	struct pnp_port *port;
L
Linus Torvalds 已提交
450

B
Bob Moore 已提交
451
	if (io->address_length == 0)
L
Linus Torvalds 已提交
452
		return;
453
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
454 455
	if (!port)
		return;
B
Bob Moore 已提交
456 457
	port->min = port->max = io->address;
	port->size = io->address_length;
L
Linus Torvalds 已提交
458 459
	port->align = 0;
	port->flags = PNP_PORT_FLAG_FIXED;
460
	pnp_register_port_resource(dev, option, port);
L
Linus Torvalds 已提交
461 462
}

463 464
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
					      struct pnp_option *option,
465
					      struct acpi_resource_memory24 *p)
L
Linus Torvalds 已提交
466
{
B
Bjorn Helgaas 已提交
467
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
468

B
Bob Moore 已提交
469
	if (p->address_length == 0)
L
Linus Torvalds 已提交
470
		return;
471
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
472 473
	if (!mem)
		return;
B
Bob Moore 已提交
474 475
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
476
	mem->align = p->alignment;
B
Bob Moore 已提交
477
	mem->size = p->address_length;
L
Linus Torvalds 已提交
478

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

482
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
483 484
}

485 486
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
					      struct pnp_option *option,
487
					      struct acpi_resource_memory32 *p)
L
Linus Torvalds 已提交
488
{
B
Bjorn Helgaas 已提交
489
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
490

B
Bob Moore 已提交
491
	if (p->address_length == 0)
L
Linus Torvalds 已提交
492
		return;
493
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
494 495
	if (!mem)
		return;
B
Bob Moore 已提交
496 497
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
498
	mem->align = p->alignment;
B
Bob Moore 已提交
499
	mem->size = p->address_length;
L
Linus Torvalds 已提交
500

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

504
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
505 506
}

507 508
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
						    struct pnp_option *option,
509
					struct acpi_resource_fixed_memory32 *p)
L
Linus Torvalds 已提交
510
{
B
Bjorn Helgaas 已提交
511
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
512

B
Bob Moore 已提交
513
	if (p->address_length == 0)
L
Linus Torvalds 已提交
514
		return;
515
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
516 517
	if (!mem)
		return;
B
Bob Moore 已提交
518 519
	mem->min = mem->max = p->address;
	mem->size = p->address_length;
L
Linus Torvalds 已提交
520 521
	mem->align = 0;

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

525
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
526 527
}

528 529
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
						struct pnp_option *option,
530
						struct acpi_resource *r)
531 532 533
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
B
Bjorn Helgaas 已提交
534 535
	struct pnp_mem *mem;
	struct pnp_port *port;
536 537 538

	status = acpi_resource_to_address64(r, p);
	if (!ACPI_SUCCESS(status)) {
B
Bjorn Helgaas 已提交
539 540
		pnp_warn("PnPACPI: failed to convert resource type %d",
			 r->type);
541 542 543 544 545 546 547
		return;
	}

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

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

L
Linus Torvalds 已提交
570 571
struct acpipnp_parse_option_s {
	struct pnp_option *option;
M
Matthieu Castet 已提交
572
	struct pnp_option *option_independent;
L
Linus Torvalds 已提交
573 574 575
	struct pnp_dev *dev;
};

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

584
	switch (res->type) {
B
Bjorn Helgaas 已提交
585
	case ACPI_RESOURCE_TYPE_IRQ:
586
		pnpacpi_parse_irq_option(dev, option, &res->data.irq);
B
Bjorn Helgaas 已提交
587
		break;
588

B
Bjorn Helgaas 已提交
589
	case ACPI_RESOURCE_TYPE_DMA:
590
		pnpacpi_parse_dma_option(dev, option, &res->data.dma);
B
Bjorn Helgaas 已提交
591
		break;
592

B
Bjorn Helgaas 已提交
593 594 595 596
	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 已提交
597
			break;
598

B
Bjorn Helgaas 已提交
599 600
		case ACPI_ACCEPTABLE_CONFIGURATION:
			priority = PNP_RES_PRIORITY_ACCEPTABLE;
M
Matthieu Castet 已提交
601
			break;
602

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

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

B
Bjorn Helgaas 已提交
629
	case ACPI_RESOURCE_TYPE_IO:
630
		pnpacpi_parse_port_option(dev, option, &res->data.io);
B
Bjorn Helgaas 已提交
631
		break;
632

B
Bjorn Helgaas 已提交
633
	case ACPI_RESOURCE_TYPE_FIXED_IO:
634 635
		pnpacpi_parse_fixed_port_option(dev, option,
					        &res->data.fixed_io);
B
Bjorn Helgaas 已提交
636
		break;
637

B
Bjorn Helgaas 已提交
638 639 640
	case ACPI_RESOURCE_TYPE_VENDOR:
	case ACPI_RESOURCE_TYPE_END_TAG:
		break;
641

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

B
Bjorn Helgaas 已提交
646
	case ACPI_RESOURCE_TYPE_MEMORY32:
647
		pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
B
Bjorn Helgaas 已提交
648
		break;
649

B
Bjorn Helgaas 已提交
650
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
651
		pnpacpi_parse_fixed_mem32_option(dev, option,
B
Bjorn Helgaas 已提交
652 653
						 &res->data.fixed_memory32);
		break;
654

B
Bjorn Helgaas 已提交
655 656 657
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
658
		pnpacpi_parse_address_option(dev, option, res);
B
Bjorn Helgaas 已提交
659
		break;
660

B
Bjorn Helgaas 已提交
661 662 663 664
	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		break;

	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
665 666
		pnpacpi_parse_ext_irq_option(dev, option,
					     &res->data.extended_irq);
B
Bjorn Helgaas 已提交
667 668 669 670 671 672
		break;

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
		break;

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

L
Linus Torvalds 已提交
678 679 680
	return AE_OK;
}

681
int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
L
Linus Torvalds 已提交
682
{
683
	acpi_handle handle = dev->data;
L
Linus Torvalds 已提交
684 685 686
	acpi_status status;
	struct acpipnp_parse_option_s parse_data;

687 688
	dev_dbg(&dev->dev, "parse resource options\n");

L
Linus Torvalds 已提交
689 690
	parse_data.option = pnp_register_independent_option(dev);
	if (!parse_data.option)
691 692
		return -ENOMEM;

M
Matthieu Castet 已提交
693
	parse_data.option_independent = parse_data.option;
L
Linus Torvalds 已提交
694
	parse_data.dev = dev;
B
Bob Moore 已提交
695
	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
B
Bjorn Helgaas 已提交
696
				     pnpacpi_option_resource, &parse_data);
L
Linus Torvalds 已提交
697

698 699 700 701 702 703
	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 已提交
704 705
}

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

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

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

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

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

	return AE_OK;
}

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

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

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

	return 0;
}

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

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

	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 已提交
807 808
}

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

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

	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 已提交
831 832
}

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

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

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

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

	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 已提交
872 873
}

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

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

	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 已提交
891 892
}

893 894
static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
				    struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
895
				    struct resource *p)
L
Linus Torvalds 已提交
896
{
897 898 899 900
	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;
901 902 903

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

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

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

	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 已提交
924 925
}

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

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

	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 已提交
943 944
}

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

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

	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 已提交
961 962
}

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

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

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