More meth updates.
[linux-2.6/linux-mips.git] / drivers / serial / 8250_acpi.c
blob7692b54a9ad662b99b8e71adf7e1647234484c03
1 /*
2 * serial/acpi.c
3 * Copyright (c) 2002-2003 Matthew Wilcox for Hewlett-Packard
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
11 #include <linux/acpi.h>
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/serial.h>
16 #include <acpi/acpi_bus.h>
18 #include <asm/io.h>
19 #include <asm/serial.h>
21 static void acpi_serial_address(struct serial_struct *req,
22 struct acpi_resource_address32 *addr32)
24 unsigned long size;
26 size = addr32->max_address_range - addr32->min_address_range + 1;
27 req->iomap_base = addr32->min_address_range;
28 req->iomem_base = ioremap(req->iomap_base, size);
29 req->io_type = SERIAL_IO_MEM;
32 static void acpi_serial_irq(struct serial_struct *req,
33 struct acpi_resource_ext_irq *ext_irq)
35 if (ext_irq->number_of_interrupts > 0) {
36 #ifdef CONFIG_IA64
37 req->irq = acpi_register_irq(ext_irq->interrupts[0],
38 ext_irq->active_high_low, ext_irq->edge_level);
39 #else
40 req->irq = ext_irq->interrupts[0];
41 #endif
45 static int acpi_serial_add(struct acpi_device *device)
47 acpi_status result;
48 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
49 struct serial_struct serial_req;
50 int line, offset = 0;
52 memset(&serial_req, 0, sizeof(serial_req));
53 result = acpi_get_current_resources(device->handle, &buffer);
54 if (ACPI_FAILURE(result)) {
55 result = -ENODEV;
56 goto out;
59 while (offset <= buffer.length) {
60 struct acpi_resource *res = buffer.pointer + offset;
61 if (res->length == 0)
62 break;
63 offset += res->length;
64 if (res->id == ACPI_RSTYPE_ADDRESS32) {
65 acpi_serial_address(&serial_req, &res->data.address32);
66 } else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
67 acpi_serial_irq(&serial_req, &res->data.extended_irq);
71 serial_req.baud_base = BASE_BAUD;
72 serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ;
74 result = 0;
75 line = register_serial(&serial_req);
76 if (line < 0)
77 result = -ENODEV;
79 out:
80 acpi_os_free(buffer.pointer);
81 return result;
84 static int acpi_serial_remove(struct acpi_device *device, int type)
86 return 0;
89 static struct acpi_driver acpi_serial_driver = {
90 .name = "serial",
91 .class = "",
92 .ids = "PNP0501",
93 .ops = {
94 .add = acpi_serial_add,
95 .remove = acpi_serial_remove,
99 static int __init acpi_serial_init(void)
101 return acpi_bus_register_driver(&acpi_serial_driver);
104 static void __exit acpi_serial_exit(void)
106 acpi_bus_unregister_driver(&acpi_serial_driver);
109 module_init(acpi_serial_init);
110 module_exit(acpi_serial_exit);