root/drivers/tty/serial/8250/8250_acorn.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. serial_card_probe
  2. serial_card_remove
  3. serial_card_init
  4. serial_card_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  linux/drivers/serial/acorn.c
   4  *
   5  *  Copyright (C) 1996-2003 Russell King.
   6  */
   7 #include <linux/module.h>
   8 #include <linux/types.h>
   9 #include <linux/tty.h>
  10 #include <linux/serial_core.h>
  11 #include <linux/errno.h>
  12 #include <linux/ioport.h>
  13 #include <linux/slab.h>
  14 #include <linux/device.h>
  15 #include <linux/init.h>
  16 
  17 #include <asm/io.h>
  18 #include <asm/ecard.h>
  19 #include <asm/string.h>
  20 
  21 #include "8250.h"
  22 
  23 #define MAX_PORTS       3
  24 
  25 struct serial_card_type {
  26         unsigned int    num_ports;
  27         unsigned int    uartclk;
  28         unsigned int    type;
  29         unsigned int    offset[MAX_PORTS];
  30 };
  31 
  32 struct serial_card_info {
  33         unsigned int    num_ports;
  34         int             ports[MAX_PORTS];
  35         void __iomem *vaddr;
  36 };
  37 
  38 static int
  39 serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
  40 {
  41         struct serial_card_info *info;
  42         struct serial_card_type *type = id->data;
  43         struct uart_8250_port uart;
  44         unsigned long bus_addr;
  45         unsigned int i;
  46 
  47         info = kzalloc(sizeof(struct serial_card_info), GFP_KERNEL);
  48         if (!info)
  49                 return -ENOMEM;
  50 
  51         info->num_ports = type->num_ports;
  52 
  53         bus_addr = ecard_resource_start(ec, type->type);
  54         info->vaddr = ecardm_iomap(ec, type->type, 0, 0);
  55         if (!info->vaddr) {
  56                 kfree(info);
  57                 return -ENOMEM;
  58         }
  59 
  60         ecard_set_drvdata(ec, info);
  61 
  62         memset(&uart, 0, sizeof(struct uart_8250_port));
  63         uart.port.irq   = ec->irq;
  64         uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
  65         uart.port.uartclk       = type->uartclk;
  66         uart.port.iotype        = UPIO_MEM;
  67         uart.port.regshift      = 2;
  68         uart.port.dev   = &ec->dev;
  69 
  70         for (i = 0; i < info->num_ports; i++) {
  71                 uart.port.membase = info->vaddr + type->offset[i];
  72                 uart.port.mapbase = bus_addr + type->offset[i];
  73 
  74                 info->ports[i] = serial8250_register_8250_port(&uart);
  75         }
  76 
  77         return 0;
  78 }
  79 
  80 static void serial_card_remove(struct expansion_card *ec)
  81 {
  82         struct serial_card_info *info = ecard_get_drvdata(ec);
  83         int i;
  84 
  85         ecard_set_drvdata(ec, NULL);
  86 
  87         for (i = 0; i < info->num_ports; i++)
  88                 if (info->ports[i] > 0)
  89                         serial8250_unregister_port(info->ports[i]);
  90 
  91         kfree(info);
  92 }
  93 
  94 static struct serial_card_type atomwide_type = {
  95         .num_ports      = 3,
  96         .uartclk        = 7372800,
  97         .type           = ECARD_RES_IOCSLOW,
  98         .offset         = { 0x2800, 0x2400, 0x2000 },
  99 };
 100 
 101 static struct serial_card_type serport_type = {
 102         .num_ports      = 2,
 103         .uartclk        = 3686400,
 104         .type           = ECARD_RES_IOCSLOW,
 105         .offset         = { 0x2000, 0x2020 },
 106 };
 107 
 108 static const struct ecard_id serial_cids[] = {
 109         { MANU_ATOMWIDE,        PROD_ATOMWIDE_3PSERIAL, &atomwide_type  },
 110         { MANU_SERPORT,         PROD_SERPORT_DSPORT,    &serport_type   },
 111         { 0xffff, 0xffff }
 112 };
 113 
 114 static struct ecard_driver serial_card_driver = {
 115         .probe          = serial_card_probe,
 116         .remove         = serial_card_remove,
 117         .id_table       = serial_cids,
 118         .drv = {
 119                 .name   = "8250_acorn",
 120         },
 121 };
 122 
 123 static int __init serial_card_init(void)
 124 {
 125         return ecard_register_driver(&serial_card_driver);
 126 }
 127 
 128 static void __exit serial_card_exit(void)
 129 {
 130         ecard_remove_driver(&serial_card_driver);
 131 }
 132 
 133 MODULE_AUTHOR("Russell King");
 134 MODULE_DESCRIPTION("Acorn 8250-compatible serial port expansion card driver");
 135 MODULE_LICENSE("GPL");
 136 
 137 module_init(serial_card_init);
 138 module_exit(serial_card_exit);

/* [<][>][^][v][top][bottom][index][help] */