0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/errno.h>
0013 #include <linux/io.h>
0014 #include <linux/platform_device.h>
0015
0016 #include "8250.h"
0017
0018 #define IOC3_UARTCLK (22000000 / 3)
0019
0020 struct ioc3_8250_data {
0021 int line;
0022 };
0023
0024 static unsigned int ioc3_serial_in(struct uart_port *p, int offset)
0025 {
0026 return readb(p->membase + (offset ^ 3));
0027 }
0028
0029 static void ioc3_serial_out(struct uart_port *p, int offset, int value)
0030 {
0031 writeb(value, p->membase + (offset ^ 3));
0032 }
0033
0034 static int serial8250_ioc3_probe(struct platform_device *pdev)
0035 {
0036 struct ioc3_8250_data *data;
0037 struct uart_8250_port up;
0038 struct resource *r;
0039 void __iomem *membase;
0040 int irq, line;
0041
0042 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0043 if (!r)
0044 return -ENODEV;
0045
0046 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
0047 if (!data)
0048 return -ENOMEM;
0049
0050 membase = devm_ioremap(&pdev->dev, r->start, resource_size(r));
0051 if (!membase)
0052 return -ENOMEM;
0053
0054 irq = platform_get_irq(pdev, 0);
0055 if (irq < 0)
0056 irq = 0;
0057
0058
0059 memset(&up, 0, sizeof(struct uart_8250_port));
0060 up.port.iotype = UPIO_MEM;
0061 up.port.uartclk = IOC3_UARTCLK;
0062 up.port.type = PORT_16550A;
0063 up.port.irq = irq;
0064 up.port.flags = (UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ);
0065 up.port.dev = &pdev->dev;
0066 up.port.membase = membase;
0067 up.port.mapbase = r->start;
0068 up.port.serial_in = ioc3_serial_in;
0069 up.port.serial_out = ioc3_serial_out;
0070 line = serial8250_register_8250_port(&up);
0071 if (line < 0)
0072 return line;
0073
0074 platform_set_drvdata(pdev, data);
0075 return 0;
0076 }
0077
0078 static int serial8250_ioc3_remove(struct platform_device *pdev)
0079 {
0080 struct ioc3_8250_data *data = platform_get_drvdata(pdev);
0081
0082 serial8250_unregister_port(data->line);
0083 return 0;
0084 }
0085
0086 static struct platform_driver serial8250_ioc3_driver = {
0087 .probe = serial8250_ioc3_probe,
0088 .remove = serial8250_ioc3_remove,
0089 .driver = {
0090 .name = "ioc3-serial8250",
0091 }
0092 };
0093
0094 module_platform_driver(serial8250_ioc3_driver);
0095
0096 MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>");
0097 MODULE_DESCRIPTION("SGI IOC3 8250 UART driver");
0098 MODULE_LICENSE("GPL");