patch-2.4.22 linux-2.4.22/drivers/acorn/char/serial-card.c
Next file: linux-2.4.22/drivers/acorn/char/serial-dualsp.c
Previous file: linux-2.4.22/drivers/acorn/char/serial-atomwide.c
Back to the patch index
Back to the overall index
- Lines: 184
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/drivers/acorn/char/serial-card.c
- Orig date:
2001-09-13 15:21:32.000000000 -0700
diff -urN linux-2.4.21/drivers/acorn/char/serial-card.c linux-2.4.22/drivers/acorn/char/serial-card.c
@@ -27,106 +27,110 @@
*/
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
#include <linux/init.h>
+#include <asm/io.h>
#include <asm/ecard.h>
#include <asm/string.h>
-#ifndef NUM_SERIALS
-#define NUM_SERIALS MY_NUMPORTS * MAX_ECARDS
-#endif
-
-#ifdef MODULE
-static int __serial_ports[NUM_SERIALS];
-static int __serial_pcount;
-static int __serial_addr[NUM_SERIALS];
-static struct expansion_card *expcard[MAX_ECARDS];
-#define ADD_ECARD(ec,card) expcard[(card)] = (ec)
-#define ADD_PORT(port,addr) \
- do { \
- __serial_ports[__serial_pcount] = (port); \
- __serial_addr[__serial_pcount] = (addr); \
- __serial_pcount += 1; \
- } while (0)
-#else
-#define ADD_ECARD(ec,card)
-#define ADD_PORT(port,addr)
-#endif
+struct serial_card_info {
+ unsigned int num_ports;
+ int ports[MAX_PORTS];
+};
-static const card_ids serial_cids[] = { MY_CARD_LIST, { 0xffff, 0xffff } };
-
-static inline int serial_register_onedev (unsigned long port, int irq)
+static inline int
+serial_register_onedev(unsigned long baddr, void *vaddr, int irq, unsigned int baud_base)
{
- struct serial_struct req;
+ struct serial_struct req;
- memset(&req, 0, sizeof(req));
- req.baud_base = MY_BAUD_BASE;
- req.irq = irq;
- req.port = port;
- req.flags = 0;
+ memset(&req, 0, sizeof(req));
+ req.irq = irq;
+ req.flags = UPF_AUTOPROBE | UPF_RESOURCES |
+ UPF_SHARE_IRQ;
+ req.baud_base = baud_base;
+ req.io_type = UPIO_MEM;
+ req.iomem_base = vaddr;
+ req.iomem_reg_shift = 2;
+ req.iomap_base = baddr;
- return register_serial(&req);
+ return register_serial(&req);
}
-static int __init INIT (void)
+static int __devinit
+serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
{
- int card = 0;
-
- ecard_startfind ();
+ struct serial_card_info *info;
+ struct serial_card_type *type = id->data;
+ unsigned long bus_addr;
+ unsigned char *virt_addr;
+ unsigned int port;
+
+ 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;
+
+ ecard_set_drvdata(ec, info);
+
+ bus_addr = ec->resource[type->type].start;
+ virt_addr = ioremap(bus_addr, ec->resource[type->type].end - bus_addr + 1);
+ if (!virt_addr) {
+ kfree(info);
+ return -ENOMEM;
+ }
- do {
- struct expansion_card *ec;
- unsigned long cardaddr;
- int port;
+ for (port = 0; port < info->num_ports; port ++) {
+ unsigned long baddr = bus_addr + type->offset[port];
+ unsigned char *vaddr = virt_addr + type->offset[port];
- ec = ecard_find (0, serial_cids);
- if (!ec)
- break;
+ info->ports[port] = serial_register_onedev(baddr, vaddr,
+ ec->irq, type->baud_base);
+ }
- cardaddr = MY_BASE_ADDRESS(ec);
+ return 0;
+}
- for (port = 0; port < MY_NUMPORTS; port ++) {
- unsigned long address;
- int line;
+static void __devexit serial_card_remove(struct expansion_card *ec)
+{
+ struct serial_card_info *info = ecard_get_drvdata(ec);
+ int i;
- address = MY_PORT_ADDRESS(port, cardaddr);
+ ecard_set_drvdata(ec, NULL);
- line = serial_register_onedev (address, ec->irq);
- if (line < 0)
- break;
- ADD_PORT(line, address);
- }
+ for (i = 0; i < info->num_ports; i++)
+ if (info->ports[i] > 0)
+ unregister_serial(info->ports[i]);
- if (port) {
- ecard_claim (ec);
- ADD_ECARD(ec, card);
- } else
- break;
- } while (++card < MAX_ECARDS);
- return card ? 0 : -ENODEV;
+ kfree(info);
}
-static void __exit EXIT (void)
+static struct ecard_driver serial_card_driver = {
+ .probe = serial_card_probe,
+ .remove = __devexit_p(serial_card_remove),
+ .id_table = serial_cids,
+};
+
+static int __init serial_card_init(void)
{
-#ifdef MODULE
- int i;
+ return ecard_register_driver(&serial_card_driver);
+}
- 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]);
-#endif
+static void __exit serial_card_exit(void)
+{
+ ecard_remove_driver(&serial_card_driver);
}
EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Russell King");
MODULE_LICENSE("GPL");
-module_init(INIT);
-module_exit(EXIT);
+module_init(serial_card_init);
+module_exit(serial_card_exit);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)