rsparser.c 26.5 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
acpi_status pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
L
Linus Torvalds 已提交
343
{
344 345
	acpi_handle handle = dev->data;

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

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

B
Bjorn Helgaas 已提交
350
	return acpi_walk_resources(handle, METHOD_NAME__CRS,
351
				   pnpacpi_allocated_resource, dev);
L
Linus Torvalds 已提交
352 353
}

354 355
static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
					    struct pnp_option *option,
356
					    struct acpi_resource_dma *p)
L
Linus Torvalds 已提交
357 358
{
	int i;
B
Bjorn Helgaas 已提交
359
	struct pnp_dma *dma;
L
Linus Torvalds 已提交
360

B
Bob Moore 已提交
361
	if (p->channel_count == 0)
L
Linus Torvalds 已提交
362
		return;
363
	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
L
Linus Torvalds 已提交
364 365 366
	if (!dma)
		return;

B
Bjorn Helgaas 已提交
367
	for (i = 0; i < p->channel_count; i++)
L
Linus Torvalds 已提交
368
		dma->map |= 1 << p->channels[i];
369 370

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

372
	pnp_register_dma_resource(dev, option, dma);
L
Linus Torvalds 已提交
373 374
}

375 376
static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
					    struct pnp_option *option,
377
					    struct acpi_resource_irq *p)
L
Linus Torvalds 已提交
378 379
{
	int i;
B
Bjorn Helgaas 已提交
380 381
	struct pnp_irq *irq;

B
Bob Moore 已提交
382
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
383
		return;
384
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
385 386 387
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
388
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
389 390
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
391
	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
L
Linus Torvalds 已提交
392

393
	pnp_register_irq_resource(dev, option, irq);
L
Linus Torvalds 已提交
394 395
}

396 397
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
						struct pnp_option *option,
398
					struct acpi_resource_extended_irq *p)
L
Linus Torvalds 已提交
399 400
{
	int i;
B
Bjorn Helgaas 已提交
401
	struct pnp_irq *irq;
L
Linus Torvalds 已提交
402

B
Bob Moore 已提交
403
	if (p->interrupt_count == 0)
L
Linus Torvalds 已提交
404
		return;
405
	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
L
Linus Torvalds 已提交
406 407 408
	if (!irq)
		return;

B
Bjorn Helgaas 已提交
409
	for (i = 0; i < p->interrupt_count; i++)
L
Linus Torvalds 已提交
410 411
		if (p->interrupts[i])
			__set_bit(p->interrupts[i], irq->map);
412
	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
L
Linus Torvalds 已提交
413

414
	pnp_register_irq_resource(dev, option, irq);
L
Linus Torvalds 已提交
415 416
}

417 418
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
					     struct pnp_option *option,
419
					     struct acpi_resource_io *io)
L
Linus Torvalds 已提交
420
{
B
Bjorn Helgaas 已提交
421
	struct pnp_port *port;
L
Linus Torvalds 已提交
422

B
Bob Moore 已提交
423
	if (io->address_length == 0)
L
Linus Torvalds 已提交
424
		return;
425
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
426 427
	if (!port)
		return;
B
Bob Moore 已提交
428 429
	port->min = io->minimum;
	port->max = io->maximum;
L
Linus Torvalds 已提交
430
	port->align = io->alignment;
B
Bob Moore 已提交
431 432
	port->size = io->address_length;
	port->flags = ACPI_DECODE_16 == io->io_decode ?
B
Bjorn Helgaas 已提交
433
	    PNP_PORT_FLAG_16BITADDR : 0;
434
	pnp_register_port_resource(dev, option, port);
L
Linus Torvalds 已提交
435 436
}

437 438
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
						   struct pnp_option *option,
439
					struct acpi_resource_fixed_io *io)
L
Linus Torvalds 已提交
440
{
B
Bjorn Helgaas 已提交
441
	struct pnp_port *port;
L
Linus Torvalds 已提交
442

B
Bob Moore 已提交
443
	if (io->address_length == 0)
L
Linus Torvalds 已提交
444
		return;
445
	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
L
Linus Torvalds 已提交
446 447
	if (!port)
		return;
B
Bob Moore 已提交
448 449
	port->min = port->max = io->address;
	port->size = io->address_length;
L
Linus Torvalds 已提交
450 451
	port->align = 0;
	port->flags = PNP_PORT_FLAG_FIXED;
452
	pnp_register_port_resource(dev, option, port);
L
Linus Torvalds 已提交
453 454
}

455 456
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
					      struct pnp_option *option,
457
					      struct acpi_resource_memory24 *p)
L
Linus Torvalds 已提交
458
{
B
Bjorn Helgaas 已提交
459
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
460

B
Bob Moore 已提交
461
	if (p->address_length == 0)
L
Linus Torvalds 已提交
462
		return;
463
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
464 465
	if (!mem)
		return;
B
Bob Moore 已提交
466 467
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
468
	mem->align = p->alignment;
B
Bob Moore 已提交
469
	mem->size = p->address_length;
L
Linus Torvalds 已提交
470

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

474
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
475 476
}

477 478
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
					      struct pnp_option *option,
479
					      struct acpi_resource_memory32 *p)
L
Linus Torvalds 已提交
480
{
B
Bjorn Helgaas 已提交
481
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
482

B
Bob Moore 已提交
483
	if (p->address_length == 0)
L
Linus Torvalds 已提交
484
		return;
485
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
486 487
	if (!mem)
		return;
B
Bob Moore 已提交
488 489
	mem->min = p->minimum;
	mem->max = p->maximum;
L
Linus Torvalds 已提交
490
	mem->align = p->alignment;
B
Bob Moore 已提交
491
	mem->size = p->address_length;
L
Linus Torvalds 已提交
492

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

496
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
497 498
}

499 500
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
						    struct pnp_option *option,
501
					struct acpi_resource_fixed_memory32 *p)
L
Linus Torvalds 已提交
502
{
B
Bjorn Helgaas 已提交
503
	struct pnp_mem *mem;
L
Linus Torvalds 已提交
504

B
Bob Moore 已提交
505
	if (p->address_length == 0)
L
Linus Torvalds 已提交
506
		return;
507
	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
L
Linus Torvalds 已提交
508 509
	if (!mem)
		return;
B
Bob Moore 已提交
510 511
	mem->min = mem->max = p->address;
	mem->size = p->address_length;
L
Linus Torvalds 已提交
512 513
	mem->align = 0;

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

517
	pnp_register_mem_resource(dev, option, mem);
L
Linus Torvalds 已提交
518 519
}

520 521
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
						struct pnp_option *option,
522
						struct acpi_resource *r)
523 524 525
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
B
Bjorn Helgaas 已提交
526 527
	struct pnp_mem *mem;
	struct pnp_port *port;
528 529 530

	status = acpi_resource_to_address64(r, p);
	if (!ACPI_SUCCESS(status)) {
B
Bjorn Helgaas 已提交
531 532
		pnp_warn("PnPACPI: failed to convert resource type %d",
			 r->type);
533 534 535 536 537 538 539
		return;
	}

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

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

L
Linus Torvalds 已提交
562 563
struct acpipnp_parse_option_s {
	struct pnp_option *option;
M
Matthieu Castet 已提交
564
	struct pnp_option *option_independent;
L
Linus Torvalds 已提交
565 566 567
	struct pnp_dev *dev;
};

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

576
	switch (res->type) {
B
Bjorn Helgaas 已提交
577
	case ACPI_RESOURCE_TYPE_IRQ:
578
		pnpacpi_parse_irq_option(dev, option, &res->data.irq);
B
Bjorn Helgaas 已提交
579
		break;
580

B
Bjorn Helgaas 已提交
581
	case ACPI_RESOURCE_TYPE_DMA:
582
		pnpacpi_parse_dma_option(dev, option, &res->data.dma);
B
Bjorn Helgaas 已提交
583
		break;
584

B
Bjorn Helgaas 已提交
585 586 587 588
	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 已提交
589
			break;
590

B
Bjorn Helgaas 已提交
591 592
		case ACPI_ACCEPTABLE_CONFIGURATION:
			priority = PNP_RES_PRIORITY_ACCEPTABLE;
M
Matthieu Castet 已提交
593
			break;
594

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

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

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

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

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

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

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

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

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

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

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

	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
		break;

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

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

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

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

L
Linus Torvalds 已提交
681 682 683
	parse_data.option = pnp_register_independent_option(dev);
	if (!parse_data.option)
		return AE_ERROR;
M
Matthieu Castet 已提交
684
	parse_data.option_independent = parse_data.option;
L
Linus Torvalds 已提交
685
	parse_data.dev = dev;
B
Bob Moore 已提交
686
	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
B
Bjorn Helgaas 已提交
687
				     pnpacpi_option_resource, &parse_data);
L
Linus Torvalds 已提交
688 689 690 691

	return status;
}

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

/*
 * Set resource
 */
static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
B
Bjorn Helgaas 已提交
715
					   void *data)
716
{
717
	int *res_cnt = data;
718 719 720

	if (pnpacpi_supported_resource(res))
		(*res_cnt)++;
L
Linus Torvalds 已提交
721 722 723
	return AE_OK;
}

B
Bjorn Helgaas 已提交
724
static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
L
Linus Torvalds 已提交
725
{
726
	struct acpi_resource **resource = data;
727 728

	if (pnpacpi_supported_resource(res)) {
729
		(*resource)->type = res->type;
730
		(*resource)->length = sizeof(struct acpi_resource);
L
Linus Torvalds 已提交
731 732 733 734 735 736
		(*resource)++;
	}

	return AE_OK;
}

737
int pnpacpi_build_resource_template(struct pnp_dev *dev,
B
Bjorn Helgaas 已提交
738
				    struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
739
{
740
	acpi_handle handle = dev->data;
L
Linus Torvalds 已提交
741 742 743 744
	struct acpi_resource *resource;
	int res_cnt = 0;
	acpi_status status;

B
Bob Moore 已提交
745
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
746
				     pnpacpi_count_resources, &res_cnt);
L
Linus Torvalds 已提交
747
	if (ACPI_FAILURE(status)) {
748
		dev_err(&dev->dev, "can't evaluate _CRS\n");
L
Linus Torvalds 已提交
749 750 751 752 753
		return -EINVAL;
	}
	if (!res_cnt)
		return -EINVAL;
	buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
754
	buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
L
Linus Torvalds 已提交
755 756
	if (!buffer->pointer)
		return -ENOMEM;
757

L
Linus Torvalds 已提交
758
	resource = (struct acpi_resource *)buffer->pointer;
B
Bob Moore 已提交
759
	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
B
Bjorn Helgaas 已提交
760
				     pnpacpi_type_resources, &resource);
L
Linus Torvalds 已提交
761 762
	if (ACPI_FAILURE(status)) {
		kfree(buffer->pointer);
763
		dev_err(&dev->dev, "can't evaluate _CRS\n");
L
Linus Torvalds 已提交
764 765 766
		return -EINVAL;
	}
	/* resource will pointer the end resource now */
B
Bob Moore 已提交
767
	resource->type = ACPI_RESOURCE_TYPE_END_TAG;
L
Linus Torvalds 已提交
768 769 770 771

	return 0;
}

772 773
static void pnpacpi_encode_irq(struct pnp_dev *dev,
			       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
774
			       struct resource *p)
L
Linus Torvalds 已提交
775
{
776
	struct acpi_resource_irq *irq = &resource->data.irq;
B
Bob Moore 已提交
777
	int triggering, polarity;
B
Bjorn Helgaas 已提交
778 779

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
780 781
	irq->triggering = triggering;
	irq->polarity = polarity;
B
Bob Moore 已提交
782
	if (triggering == ACPI_EDGE_SENSITIVE)
783
		irq->sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
784
	else
785 786 787
		irq->sharable = ACPI_SHARED;
	irq->interrupt_count = 1;
	irq->interrupts[0] = p->start;
788 789 790 791 792

	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 已提交
793 794
}

795 796
static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
				   struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
797
				   struct resource *p)
L
Linus Torvalds 已提交
798
{
799
	struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
B
Bob Moore 已提交
800
	int triggering, polarity;
B
Bjorn Helgaas 已提交
801 802

	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
803 804 805
	extended_irq->producer_consumer = ACPI_CONSUMER;
	extended_irq->triggering = triggering;
	extended_irq->polarity = polarity;
B
Bob Moore 已提交
806
	if (triggering == ACPI_EDGE_SENSITIVE)
807
		extended_irq->sharable = ACPI_EXCLUSIVE;
L
Linus Torvalds 已提交
808
	else
809 810 811
		extended_irq->sharable = ACPI_SHARED;
	extended_irq->interrupt_count = 1;
	extended_irq->interrupts[0] = p->start;
812 813 814 815 816

	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 已提交
817 818
}

819 820
static void pnpacpi_encode_dma(struct pnp_dev *dev,
			       struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
821
			       struct resource *p)
L
Linus Torvalds 已提交
822
{
823 824
	struct acpi_resource_dma *dma = &resource->data.dma;

L
Linus Torvalds 已提交
825
	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
826
	switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
B
Bjorn Helgaas 已提交
827
	case IORESOURCE_DMA_TYPEA:
828
		dma->type = ACPI_TYPE_A;
B
Bjorn Helgaas 已提交
829 830
		break;
	case IORESOURCE_DMA_TYPEB:
831
		dma->type = ACPI_TYPE_B;
B
Bjorn Helgaas 已提交
832 833
		break;
	case IORESOURCE_DMA_TYPEF:
834
		dma->type = ACPI_TYPE_F;
B
Bjorn Helgaas 已提交
835 836
		break;
	default:
837
		dma->type = ACPI_COMPATIBILITY;
838 839 840
	}

	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
B
Bjorn Helgaas 已提交
841
	case IORESOURCE_DMA_8BIT:
842
		dma->transfer = ACPI_TRANSFER_8;
B
Bjorn Helgaas 已提交
843 844
		break;
	case IORESOURCE_DMA_8AND16BIT:
845
		dma->transfer = ACPI_TRANSFER_8_16;
B
Bjorn Helgaas 已提交
846 847
		break;
	default:
848
		dma->transfer = ACPI_TRANSFER_16;
849 850
	}

851 852 853
	dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
	dma->channel_count = 1;
	dma->channels[0] = p->start;
854 855 856 857

	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 已提交
858 859
}

860 861
static void pnpacpi_encode_io(struct pnp_dev *dev,
			      struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
862
			      struct resource *p)
L
Linus Torvalds 已提交
863
{
864 865
	struct acpi_resource_io *io = &resource->data.io;

L
Linus Torvalds 已提交
866
	/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
867
	io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
B
Bjorn Helgaas 已提交
868
	    ACPI_DECODE_16 : ACPI_DECODE_10;
869 870 871 872
	io->minimum = p->start;
	io->maximum = p->end;
	io->alignment = 0;	/* Correct? */
	io->address_length = p->end - p->start + 1;
873 874 875 876

	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 已提交
877 878
}

879 880
static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
				    struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
881
				    struct resource *p)
L
Linus Torvalds 已提交
882
{
883 884 885 886
	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;
887 888 889

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

892 893
static void pnpacpi_encode_mem24(struct pnp_dev *dev,
				 struct acpi_resource *resource,
B
Bjorn Helgaas 已提交
894
				 struct resource *p)
L
Linus Torvalds 已提交
895
{
896 897
	struct acpi_resource_memory24 *memory24 = &resource->data.memory24;

L
Linus Torvalds 已提交
898
	/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
899
	memory24->write_protect =
B
Bjorn Helgaas 已提交
900 901
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
902 903 904 905
	memory24->minimum = p->start;
	memory24->maximum = p->end;
	memory24->alignment = 0;
	memory24->address_length = p->end - p->start + 1;
906 907 908 909

	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 已提交
910 911
}

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

	memory32->write_protect =
B
Bjorn Helgaas 已提交
919 920
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
921 922 923 924
	memory32->minimum = p->start;
	memory32->maximum = p->end;
	memory32->alignment = 0;
	memory32->address_length = p->end - p->start + 1;
925 926 927 928

	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 已提交
929 930
}

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

	fixed_memory32->write_protect =
B
Bjorn Helgaas 已提交
938 939
	    (p->flags & IORESOURCE_MEM_WRITEABLE) ?
	    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
940 941
	fixed_memory32->address = p->start;
	fixed_memory32->address_length = p->end - p->start + 1;
942 943 944 945 946

	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 已提交
947 948
}

949
int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
L
Linus Torvalds 已提交
950 951 952
{
	int i = 0;
	/* pnpacpi_build_resource_template allocates extra mem */
B
Bjorn Helgaas 已提交
953
	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
954
	struct acpi_resource *resource = buffer->pointer;
L
Linus Torvalds 已提交
955 956
	int port = 0, irq = 0, dma = 0, mem = 0;

957
	dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
L
Linus Torvalds 已提交
958
	while (i < res_cnt) {
B
Bjorn Helgaas 已提交
959
		switch (resource->type) {
B
Bob Moore 已提交
960
		case ACPI_RESOURCE_TYPE_IRQ:
961
			pnpacpi_encode_irq(dev, resource,
962
			       pnp_get_resource(dev, IORESOURCE_IRQ, irq));
L
Linus Torvalds 已提交
963 964 965
			irq++;
			break;

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