Commit 0fa7474a authored by Russell King's avatar Russell King

[SERIAL] 8250: add probe and remove device driver methods.

This change allows platform devices named "serial8250" to provide
lists of serial ports to the 8250 driver at runtime, in addition to
the hard coded table in include/asm-*/serial.h.

The next step is to deprecate the tables in serial.h.
parent fcc32e8d
......@@ -29,7 +29,8 @@
#include <linux/sysrq.h>
#include <linux/serial_reg.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/serial_8250.h>
#include <linux/circ_buf.h>
#include <linux/delay.h>
#include <linux/device.h>
......@@ -2174,6 +2175,55 @@ void serial8250_resume_port(int line)
uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
}
/*
* Register a set of serial devices attached to a platform device. The
* list is terminated with a zero flags entry, which means we expect
* all entries to have at least UPF_AUTOPROBE set.
*/
static int __devinit serial8250_probe(struct device *dev)
{
struct plat_serial8250_port *p = dev->platform_data;
struct uart_port port;
memset(&port, 0, sizeof(struct uart_port));
for (; p && p->flags != 0; p++) {
port.iobase = p->iobase;
port.membase = p->membase;
port.irq = p->irq;
port.uartclk = p->uartclk;
port.regshift = p->regshift;
port.iotype = p->iotype;
port.flags = p->flags;
port.mapbase = p->mapbase;
port.dev = dev;
if (share_irqs)
port.flags |= UPF_SHARE_IRQ;
serial8250_register_port(&port);
}
return 0;
}
/*
* Remove a platform device. We only remove serial ports from this
* platform device if it actually added any in the first place (iow,
* dev->platform_data is non-NULL.)
*/
static int __devexit serial8250_remove(struct device *dev)
{
int i;
if (dev->platform_data) {
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
if (up->port.dev == dev)
serial8250_unregister_port(i);
}
}
return 0;
}
static int serial8250_suspend(struct device *dev, u32 state, u32 level)
{
int i;
......@@ -2211,7 +2261,8 @@ static int serial8250_resume(struct device *dev, u32 level)
static struct device_driver serial8250_isa_driver = {
.name = "serial8250",
.bus = &platform_bus_type,
.probe = serial8250_probe,
.remove = serial8250_remove,
.suspend = serial8250_suspend,
.resume = serial8250_resume,
};
......
/*
* linux/include/linux/serial_8250.h
*
* Copyright (C) 2004 Russell King
*
* 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 of the License, or
* (at your option) any later version.
*/
#ifndef _LINUX_SERIAL_8250_H
#define _LINUX_SERIAL_8250_H
#include <linux/serial_core.h>
#include <linux/device.h>
struct plat_serial8250_port {
unsigned long iobase; /* io base address */
void __iomem *membase; /* ioremap cookie or NULL */
unsigned long mapbase; /* resource base */
unsigned int irq; /* interrupt number */
unsigned int uartclk; /* UART clock rate */
unsigned char regshift; /* register shift */
unsigned char iotype; /* UPIO_* */
unsigned int flags; /* UPF_* flags */
};
#endif
......@@ -17,6 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef LINUX_SERIAL_CORE_H
#define LINUX_SERIAL_CORE_H
/*
* The type definitions. These are from Ted Ts'o's serial.h
......@@ -96,6 +98,7 @@
#include <linux/circ_buf.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/tty.h>
struct uart_port;
struct uart_info;
......@@ -455,3 +458,5 @@ uart_handle_cts_change(struct uart_port *port, unsigned int status)
!((cflag) & CLOCAL))
#endif
#endif /* LINUX_SERIAL_CORE_H */
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