1 #include <linux/device.h> 2 #include <linux/kernel.h> 3 #include <linux/module.h> 4 #include <linux/mcb.h> 5 #include <linux/serial.h> 6 #include <linux/serial_core.h> 7 #include <linux/serial_8250.h> 8 #include <uapi/linux/serial_core.h> 9 10 struct serial_8250_men_mcb_data { 11 struct uart_8250_port uart; 12 int line; 13 }; 14 15 /* 16 * The Z125 16550-compatible UART has no fixed base clock assigned 17 * So, depending on the board we're on, we need to adjust the 18 * parameter in order to really set the correct baudrate, and 19 * do so if possible without user interaction 20 */ 21 static u32 men_z125_lookup_uartclk(struct mcb_device *mdev) 22 { 23 /* use default value if board is not available below */ 24 u32 clkval = 1041666; 25 26 dev_info(&mdev->dev, "%s on board %s\n", 27 dev_name(&mdev->dev), 28 mdev->bus->name); 29 if (strncmp(mdev->bus->name, "F075", 4) == 0) 30 clkval = 1041666; 31 else if (strncmp(mdev->bus->name, "F216", 4) == 0) 32 clkval = 1843200; 33 else if (strncmp(mdev->bus->name, "G215", 4) == 0) 34 clkval = 1843200; 35 else 36 dev_info(&mdev->dev, 37 "board not detected, using default uartclk\n"); 38 39 clkval = clkval << 4; 40 41 return clkval; 42 } 43 44 static int serial_8250_men_mcb_probe(struct mcb_device *mdev, 45 const struct mcb_device_id *id) 46 { 47 struct serial_8250_men_mcb_data *data; 48 struct resource *mem; 49 50 data = devm_kzalloc(&mdev->dev, 51 sizeof(struct serial_8250_men_mcb_data), 52 GFP_KERNEL); 53 if (!data) 54 return -ENOMEM; 55 56 mcb_set_drvdata(mdev, data); 57 data->uart.port.dev = mdev->dma_dev; 58 spin_lock_init(&data->uart.port.lock); 59 60 data->uart.port.type = PORT_16550; 61 data->uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; 62 data->uart.port.iotype = UPIO_MEM; 63 data->uart.port.uartclk = men_z125_lookup_uartclk(mdev); 64 data->uart.port.regshift = 0; 65 data->uart.port.fifosize = 60; 66 67 mem = mcb_get_resource(mdev, IORESOURCE_MEM); 68 if (mem == NULL) 69 return -ENXIO; 70 71 data->uart.port.irq = mcb_get_irq(mdev); 72 73 data->uart.port.membase = devm_ioremap_resource(&mdev->dev, mem); 74 if (IS_ERR(data->uart.port.membase)) 75 return PTR_ERR_OR_ZERO(data->uart.port.membase); 76 77 data->uart.port.mapbase = (unsigned long) mem->start; 78 data->uart.port.iobase = data->uart.port.mapbase; 79 80 /* ok, register the port */ 81 data->line = serial8250_register_8250_port(&data->uart); 82 if (data->line < 0) 83 return data->line; 84 85 dev_info(&mdev->dev, "found 16Z125 UART: ttyS%d\n", data->line); 86 87 return 0; 88 } 89 90 static void serial_8250_men_mcb_remove(struct mcb_device *mdev) 91 { 92 struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev); 93 94 if (data) 95 serial8250_unregister_port(data->line); 96 } 97 98 static const struct mcb_device_id serial_8250_men_mcb_ids[] = { 99 { .device = 0x7d }, 100 { } 101 }; 102 MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids); 103 104 static struct mcb_driver mcb_driver = { 105 .driver = { 106 .name = "8250_men_mcb", 107 .owner = THIS_MODULE, 108 }, 109 .probe = serial_8250_men_mcb_probe, 110 .remove = serial_8250_men_mcb_remove, 111 .id_table = serial_8250_men_mcb_ids, 112 }; 113 module_mcb_driver(mcb_driver); 114 115 MODULE_LICENSE("GPL v2"); 116 MODULE_DESCRIPTION("MEN 16z125 8250 UART driver"); 117 MODULE_AUTHOR("Michael Moese <michael.moese@men.de"); 118 MODULE_ALIAS("mcb:16z125"); 119