Commit 5425c22f authored by Russell King's avatar Russell King

[ARM] Acorn serial port driver update

This cset combines the Atomwide and The Serial Port 16550 driver
modules into one "8250_acorn.c" driver.  This new module takes full
advantage of the LDM-based expansion card facilities.
parent 3ecf65ae
......@@ -8,8 +8,6 @@ obj-rpc := keyb_ps2.o
obj-clps7500 := keyb_ps2.o defkeymap-acorn.o
obj-$(CONFIG_RPCMOUSE) += mouse_rpc.o
obj-$(CONFIG_ATOMWIDE_SERIAL) += serial-atomwide.o
obj-$(CONFIG_DUALSP_SERIAL) += serial-dualsp.o
obj-$(CONFIG_ARCH_ACORN) += defkeymap-acorn.o i2c.o pcf8583.o
obj-$(CONFIG_L7200_KEYB) += defkeymap-l7200.o keyb_l7200.o
......
/*
* linux/arch/arm/drivers/char/serial-atomwide.c
*
* Copyright (C) 1996 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Changelog:
* 02-05-1996 RMK Created
* 07-05-1996 RMK Altered for greater number of cards.
* 30-07-1996 RMK Now uses generic card code.
*/
#define MY_CARD_LIST { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL }
#define MY_NUMPORTS 3
#define MY_BAUD_BASE (7372800 / 16)
#define MY_BASE_ADDRESS(ec) \
ecard_address ((ec), ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2)
#define MY_PORT_ADDRESS(port,cardaddr) \
((cardaddr) + 0x200 - (port) * 0x100)
#include "serial-card.c"
/*
* linux/drivers/acorn/char/serial-card.c
*
* Copyright (C) 1996-1999 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* A generic handler of serial expansion cards that use 16550s or
* the like.
*
* Definitions:
* MY_PRODS Product numbers to identify this card by
* MY_MANUS Manufacturer numbers to identify this card by
* MY_NUMPORTS Number of ports per card
* MY_BAUD_BASE Baud base for the card
* MY_INIT Initialisation routine name
* MY_BASE_ADDRESS(ec) Return base address for ports
* MY_PORT_ADDRESS
* (port,cardaddr) Return address for port using base address
* from above.
*
* Changelog:
* 30-07-1996 RMK Created
* 22-04-1998 RMK Removed old register_pre_init_serial
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/serial.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <asm/ecard.h>
#include <asm/string.h>
#ifndef NUM_SERIALS
#define NUM_SERIALS MY_NUMPORTS * MAX_ECARDS
#endif
static int serial_ports[NUM_SERIALS];
static int serial_pcount;
static int serial_addr[NUM_SERIALS];
static struct expansion_card *expcard[MAX_ECARDS];
static const card_ids serial_cids[] = { MY_CARD_LIST, { 0xffff, 0xffff } };
static inline int serial_register_onedev (unsigned long port, int irq)
{
struct serial_struct req;
memset(&req, 0, sizeof(req));
req.baud_base = MY_BAUD_BASE;
req.irq = irq;
req.port = port;
req.flags = 0;
return register_serial(&req);
}
static int __init serial_card_init(void)
{
int card = 0;
ecard_startfind ();
do {
struct expansion_card *ec;
unsigned long cardaddr;
int port;
ec = ecard_find (0, serial_cids);
if (!ec)
break;
cardaddr = MY_BASE_ADDRESS(ec);
for (port = 0; port < MY_NUMPORTS; port ++) {
unsigned long address;
int line;
address = MY_PORT_ADDRESS(port, cardaddr);
line = serial_register_onedev (address, ec->irq);
if (line < 0)
break;
serial_ports[serial_pcount] = line;
serial_addr[serial_pcount] = address;
serial_pcount += 1;
}
if (port) {
ecard_claim (ec);
expcard[card] = ec;
} else
break;
} while (++card < MAX_ECARDS);
return card ? 0 : -ENODEV;
}
static void __exit serial_card_exit(void)
{
int i;
for (i = 0; i < serial_pcount; i++) {
unregister_serial(serial_ports[i]);
release_region(serial_addr[i], 8);
}
for (i = 0; i < MAX_ECARDS; i++)
if (expcard[i])
ecard_release (expcard[i]);
}
MODULE_AUTHOR("Russell King");
MODULE_LICENSE("GPL");
module_init(serial_card_init);
module_exit(serial_card_exit);
/*
* linux/drivers/acorn/char/serial-dualsp.c
*
* Copyright (C) 1996 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Changelog:
* 30-07-1996 RMK Created
*/
#define MY_CARD_LIST { MANU_SERPORT, PROD_SERPORT_DSPORT }
#define MY_NUMPORTS 2
#define MY_BAUD_BASE (3686400 / 16)
#define MY_BASE_ADDRESS(ec) \
ecard_address (ec, ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2)
#define MY_PORT_ADDRESS(port,cardaddress) \
((cardaddress) + (port) * 8)
#include "serial-card.c"
/*
* linux/drivers/serial/acorn.c
*
* Copyright (C) 1996-2002 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/serial.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/init.h>
#include <asm/ecard.h>
#include <asm/string.h>
#define MAX_PORTS 3
struct serial_card_type {
unsigned int num_ports;
unsigned int baud_base;
int type;
int speed;
int offset[MAX_PORTS];
};
struct serial_card_info {
unsigned int num_ports;
int ports[MAX_PORTS];
unsigned long base[MAX_PORTS];
};
static inline int serial_register_onedev(unsigned long port, int irq, unsigned int baud_base)
{
struct serial_struct req;
memset(&req, 0, sizeof(req));
req.baud_base = baud_base;
req.irq = irq;
req.port = port;
req.flags = 0;
return register_serial(&req);
}
static int __devinit serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
{
struct serial_card_info *info;
struct serial_card_type *type = id->data;
unsigned long cardaddr, address;
int port;
ecard_claim (ec);
info = kmalloc(sizeof(struct serial_card_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
memset(info, 0, sizeof(struct serial_card_info));
info->num_ports = type->num_ports;
cardaddr = ecard_address(ec, type->type, type->speed);
for (port = 0; port < info->num_ports; port ++) {
address = cardaddr + type->offset[port];
info->ports[port] = -1;
info->base[port] = address;
if (!request_region(address, 8, "acornserial"))
continue;
info->ports[port] = serial_register_onedev(address, ec->irq, type->baud_base);
if (info->ports[port] < 0)
break;
}
return 0;
}
static void __devexit serial_card_remove(struct expansion_card *ec)
{
struct serial_card_info *info = ecard_get_drvdata(ec);
int i;
ecard_set_drvdata(ec, NULL);
for (i = 0; i < info->num_ports; i++) {
if (info->ports[i] > 0) {
unregister_serial(info->ports[i]);
release_region(info->base[i], 8);
}
}
kfree(info);
ecard_release(ec);
}
static struct serial_card_type atomwide_type = {
.num_ports = 3,
.baud_base = 7372800 / 16,
.type = ECARD_IOC,
.speed = ECARD_SLOW,
.offset = { 0xa00, 0x900, 0x800 },
};
static struct serial_card_type serport_type = {
.num_ports = 2,
.baud_base = 3686400 / 16,
.type = ECARD_IOC,
.speed = ECARD_SLOW,
.offset = { 0x800, 0x808 },
};
static const struct ecard_id serial_cids[] = {
{ MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL, &atomwide_type },
{ MANU_SERPORT, PROD_SERPORT_DSPORT, &serport_type },
{ 0xffff, 0xffff }
};
static struct ecard_driver serial_card_driver = {
.probe = serial_card_probe,
.remove = __devexit_p(serial_card_remove),
.id_table = serial_cids,
.drv = {
.name = "acornserial",
},
};
static int __init serial_card_init(void)
{
return ecard_register_driver(&serial_card_driver);
}
static void __exit serial_card_exit(void)
{
ecard_remove_driver(&serial_card_driver);
}
MODULE_AUTHOR("Russell King");
MODULE_LICENSE("GPL");
module_init(serial_card_init);
module_exit(serial_card_exit);
......@@ -103,20 +103,15 @@ CONFIG_SERIAL_8250_MULTIPORT
CONFIG_SERIAL_8250_RSA
::: To be written :::
CONFIG_ATOMWIDE_SERIAL
If you have an Atomwide Serial card for an Acorn system, say Y to
this option. The driver can handle 1, 2, or 3 port cards.
If unsure, say N.
CONFIG_DUALSP_SERIAL
If you have the Serial Port's dual serial card for an Acorn system,
say Y to this option. If unsure, say N.
CONFIG_SERIAL_8250_ACORN
If you have an Atomwide Serial card or Serial Port card for an Acorn
system, say Y to this option. The driver can handle 1, 2, or 3 port
cards. If unsure, say N.
CONFIG_SERIAL_ANAKIN
::: To be written :::
CONFIG_SERIAL_ANAKIN_CONSOLE
::: To be written :::
CONFIG_SERIAL_ANAKIN_CONSOLE
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
......@@ -149,8 +144,6 @@ CONFIG_SERIAL_CLPS711X
::: To be written :::
CONFIG_SERIAL_CLPS711X_CONSOLE
::: To be written :::
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
......
......@@ -22,8 +22,7 @@ dep_bool ' Support RSA serial ports' CONFIG_SERIAL_8250_RSA $CONFIG_SERIAL_8250
comment 'Non-8250 serial port support'
if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate 'Acorn Atomwide 16550 serial port support' CONFIG_ATOMWIDE_SERIAL $CONFIG_ARCH_ACORN $CONFIG_SERIAL_8250
dep_tristate 'Acorn Dual 16550 serial port support' CONFIG_DUALSP_SERIAL $CONFIG_ARCH_ACORN $CONFIG_SERIAL_8250
dep_tristate 'Acorn expansion card serial port support' CONFIG_SERIAL_8250_ACORN $CONFIG_ARCH_ACORN $CONFIG_SERIAL_8250
dep_bool 'Anakin serial port support' CONFIG_SERIAL_ANAKIN $CONFIG_ARCH_ANAKIN
dep_bool ' Console on Anakin serial port' CONFIG_SERIAL_ANAKIN_CONSOLE $CONFIG_SERIAL_ANAKIN
if [ "$CONFIG_SERIAL_ANAKIN" = "y" ]; then
......
......@@ -13,6 +13,7 @@ obj-$(CONFIG_SERIAL_CORE) += core.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y)
obj-$(CONFIG_SERIAL_8250_CS) += 8250_cs.o
obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
obj-$(CONFIG_SERIAL_ANAKIN) += anakin.o
obj-$(CONFIG_SERIAL_AMBA) += amba.o
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
......
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