Commit 39954714 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-serial

into home.osdl.org:/home/torvalds/v2.5/linux
parents 4bf54397 aa66974b
/* /*
* serial/acpi.c
* Copyright (c) 2002-2003 Matthew Wilcox for Hewlett-Packard * Copyright (c) 2002-2003 Matthew Wilcox for Hewlett-Packard
* Copyright (C) 2004 Hewlett-Packard Co
* Bjorn Helgaas <bjorn.helgaas@hp.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,13 +12,21 @@ ...@@ -11,13 +12,21 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/tty.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/serial.h> #include <asm/serial.h>
struct serial_private {
int line;
void *iomem_base;
};
static acpi_status acpi_serial_mmio(struct serial_struct *req, static acpi_status acpi_serial_mmio(struct serial_struct *req,
struct acpi_resource_address64 *addr) struct acpi_resource_address64 *addr)
{ {
...@@ -94,38 +103,72 @@ static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data) ...@@ -94,38 +103,72 @@ static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data)
static int acpi_serial_add(struct acpi_device *device) static int acpi_serial_add(struct acpi_device *device)
{ {
struct serial_private *priv;
acpi_status status; acpi_status status;
struct serial_struct serial_req; struct serial_struct serial_req;
int line; int result;
memset(&serial_req, 0, sizeof(serial_req)); memset(&serial_req, 0, sizeof(serial_req));
priv = kmalloc(sizeof(struct serial_private), GFP_KERNEL);
if (!priv) {
result = -ENOMEM;
goto fail;
}
memset(priv, 0, sizeof(*priv));
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
acpi_serial_resource, &serial_req); acpi_serial_resource, &serial_req);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status)) {
return -ENODEV; result = -ENODEV;
goto fail;
}
if (!serial_req.iomem_base && !serial_req.port) { if (serial_req.iomem_base)
priv->iomem_base = serial_req.iomem_base;
else if (!serial_req.port) {
printk(KERN_ERR "%s: no iomem or port address in %s _CRS\n", printk(KERN_ERR "%s: no iomem or port address in %s _CRS\n",
__FUNCTION__, device->pnp.bus_id); __FUNCTION__, device->pnp.bus_id);
return -ENODEV; result = -ENODEV;
goto fail;
} }
serial_req.baud_base = BASE_BAUD; serial_req.baud_base = BASE_BAUD;
serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ; serial_req.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF |
UPF_AUTO_IRQ | UPF_RESOURCES;
line = register_serial(&serial_req);
if (line < 0) { priv->line = register_serial(&serial_req);
printk(KERN_WARNING "Couldn't register serial port %s: %d", if (priv->line < 0) {
device->pnp.bus_id, line); printk(KERN_WARNING "Couldn't register serial port %s: %d\n",
return -ENODEV; device->pnp.bus_id, priv->line);
result = -ENODEV;
goto fail;
} }
acpi_driver_data(device) = priv;
return 0; return 0;
fail:
if (serial_req.iomem_base)
iounmap(serial_req.iomem_base);
kfree(priv);
return result;
} }
static int acpi_serial_remove(struct acpi_device *device, int type) static int acpi_serial_remove(struct acpi_device *device, int type)
{ {
struct serial_private *priv;
if (!device || !acpi_driver_data(device))
return -EINVAL;
priv = acpi_driver_data(device);
unregister_serial(priv->line);
if (priv->iomem_base)
iounmap(priv->iomem_base);
kfree(priv);
return 0; return 0;
} }
......
...@@ -185,7 +185,7 @@ setup_serial_hcdp(void *tablep) ...@@ -185,7 +185,7 @@ setup_serial_hcdp(void *tablep)
#else #else
port.irq = gsi; port.irq = gsi;
#endif #endif
port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_RESOURCES;
if (gsi) if (gsi)
port.flags |= ASYNC_AUTO_IRQ; port.flags |= ASYNC_AUTO_IRQ;
......
...@@ -62,6 +62,15 @@ config SERIAL_8250_CONSOLE ...@@ -62,6 +62,15 @@ config SERIAL_8250_CONSOLE
If unsure, say N. If unsure, say N.
config SERIAL_8250_HCDP
bool "Console device discovery via EFI HCDP table"
depends on IA64
depends on SERIAL_8250_CONSOLE=y
---help---
If you wish to make the serial console port described by the EFI
HCDP table available for use as serial console, say Y here. See
<http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf>.
config SERIAL_8250_CS config SERIAL_8250_CS
tristate "8250/16550 PCMCIA device support" tristate "8250/16550 PCMCIA device support"
depends on PCMCIA && SERIAL_8250 depends on PCMCIA && SERIAL_8250
...@@ -84,15 +93,6 @@ config SERIAL_8250_ACPI ...@@ -84,15 +93,6 @@ config SERIAL_8250_ACPI
If you wish to enable serial port discovery via the ACPI If you wish to enable serial port discovery via the ACPI
namespace, say Y here. If unsure, say N. namespace, say Y here. If unsure, say N.
config SERIAL_8250_HCDP
bool "8250/16550 device discovery support via EFI HCDP table"
depends on IA64 && SERIAL_8250
---help---
If you wish to make the serial console port described by the EFI
HCDP table available for use as serial console or general
purpose port, say Y here. See
<http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf>.
config SERIAL_8250_NR_UARTS config SERIAL_8250_NR_UARTS
int "Maximum number of non-legacy 8250/16550 serial ports" int "Maximum number of non-legacy 8250/16550 serial ports"
depends on SERIAL_8250 depends on SERIAL_8250
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment