Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / tty / serial / 8250 / 8250_men_mcb.c
bloba78ef35c81877e17f6166c770a6593b350f0fe60
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/device.h>
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/io.h>
6 #include <linux/mcb.h>
7 #include <linux/serial.h>
8 #include <linux/serial_core.h>
9 #include <linux/serial_8250.h>
11 #define MEN_UART_ID_Z025 0x19
12 #define MEN_UART_ID_Z057 0x39
13 #define MEN_UART_ID_Z125 0x7d
16 * IP Cores Z025 and Z057 can have up to 4 UART
17 * The UARTs available are stored in a global
18 * register saved in physical address + 0x40
19 * Is saved as follows:
21 * 7 0
22 * +------+-------+-------+-------+-------+-------+-------+-------+
23 * |UART4 | UART3 | UART2 | UART1 | U4irq | U3irq | U2irq | U1irq |
24 * +------+-------+-------+-------+-------+-------+-------+-------+
26 #define MEN_UART1_MASK 0x01
27 #define MEN_UART2_MASK 0x02
28 #define MEN_UART3_MASK 0x04
29 #define MEN_UART4_MASK 0x08
31 #define MEN_Z125_UARTS_AVAILABLE 0x01
33 #define MEN_Z025_MAX_UARTS 4
34 #define MEN_UART_MEM_SIZE 0x10
35 #define MEM_UART_REGISTER_SIZE 0x01
36 #define MEN_Z025_REGISTER_OFFSET 0x40
38 #define MEN_UART1_OFFSET 0
39 #define MEN_UART2_OFFSET (MEN_UART1_OFFSET + MEN_UART_MEM_SIZE)
40 #define MEN_UART3_OFFSET (MEN_UART2_OFFSET + MEN_UART_MEM_SIZE)
41 #define MEN_UART4_OFFSET (MEN_UART3_OFFSET + MEN_UART_MEM_SIZE)
43 #define MEN_READ_REGISTER(addr) readb(addr)
45 #define MAX_PORTS 4
47 struct serial_8250_men_mcb_data {
48 int num_ports;
49 int line[MAX_PORTS];
50 unsigned int offset[MAX_PORTS];
54 * The Z125 16550-compatible UART has no fixed base clock assigned
55 * So, depending on the board we're on, we need to adjust the
56 * parameter in order to really set the correct baudrate, and
57 * do so if possible without user interaction
59 static u32 men_lookup_uartclk(struct mcb_device *mdev)
61 /* use default value if board is not available below */
62 u32 clkval = 1041666;
64 dev_info(&mdev->dev, "%s on board %s\n",
65 dev_name(&mdev->dev),
66 mdev->bus->name);
67 if (strncmp(mdev->bus->name, "F075", 4) == 0)
68 clkval = 1041666;
69 else if (strncmp(mdev->bus->name, "F216", 4) == 0)
70 clkval = 1843200;
71 else if (strncmp(mdev->bus->name, "F210", 4) == 0)
72 clkval = 115200;
73 else if (strstr(mdev->bus->name, "215"))
74 clkval = 1843200;
75 else
76 dev_info(&mdev->dev,
77 "board not detected, using default uartclk\n");
79 clkval = clkval << 4;
81 return clkval;
84 static int read_uarts_available_from_register(struct resource *mem_res,
85 u8 *uarts_available)
87 void __iomem *mem;
88 int reg_value;
90 if (!request_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
91 MEM_UART_REGISTER_SIZE, KBUILD_MODNAME)) {
92 return -EBUSY;
95 mem = ioremap(mem_res->start + MEN_Z025_REGISTER_OFFSET,
96 MEM_UART_REGISTER_SIZE);
97 if (!mem) {
98 release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
99 MEM_UART_REGISTER_SIZE);
100 return -ENOMEM;
103 reg_value = MEN_READ_REGISTER(mem);
105 iounmap(mem);
107 release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
108 MEM_UART_REGISTER_SIZE);
110 *uarts_available = reg_value >> 4;
112 return 0;
115 static int read_serial_data(struct mcb_device *mdev,
116 struct resource *mem_res,
117 struct serial_8250_men_mcb_data *serial_data)
119 u8 uarts_available;
120 int count = 0;
121 int mask;
122 int res;
123 int i;
125 res = read_uarts_available_from_register(mem_res, &uarts_available);
126 if (res < 0)
127 return res;
129 for (i = 0; i < MAX_PORTS; i++) {
130 mask = 0x1 << i;
131 switch (uarts_available & mask) {
132 case MEN_UART1_MASK:
133 serial_data->offset[count] = MEN_UART1_OFFSET;
134 count++;
135 break;
136 case MEN_UART2_MASK:
137 serial_data->offset[count] = MEN_UART2_OFFSET;
138 count++;
139 break;
140 case MEN_UART3_MASK:
141 serial_data->offset[count] = MEN_UART3_OFFSET;
142 count++;
143 break;
144 case MEN_UART4_MASK:
145 serial_data->offset[count] = MEN_UART4_OFFSET;
146 count++;
147 break;
148 default:
149 return -EINVAL;
153 if (count <= 0 || count > MAX_PORTS) {
154 dev_err(&mdev->dev, "unexpected number of ports: %u\n",
155 count);
156 return -ENODEV;
159 serial_data->num_ports = count;
161 return 0;
164 static int init_serial_data(struct mcb_device *mdev,
165 struct resource *mem_res,
166 struct serial_8250_men_mcb_data *serial_data)
168 switch (mdev->id) {
169 case MEN_UART_ID_Z125:
170 serial_data->num_ports = 1;
171 serial_data->offset[0] = 0;
172 return 0;
173 case MEN_UART_ID_Z025:
174 case MEN_UART_ID_Z057:
175 return read_serial_data(mdev, mem_res, serial_data);
176 default:
177 dev_err(&mdev->dev, "no supported device!\n");
178 return -ENODEV;
182 static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
183 const struct mcb_device_id *id)
185 struct uart_8250_port uart;
186 struct serial_8250_men_mcb_data *data;
187 struct resource *mem;
188 int i;
189 int res;
191 mem = mcb_get_resource(mdev, IORESOURCE_MEM);
192 if (mem == NULL)
193 return -ENXIO;
195 data = devm_kzalloc(&mdev->dev,
196 sizeof(struct serial_8250_men_mcb_data),
197 GFP_KERNEL);
198 if (!data)
199 return -ENOMEM;
201 res = init_serial_data(mdev, mem, data);
202 if (res < 0)
203 return res;
205 dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n",
206 mdev->id, data->num_ports);
208 mcb_set_drvdata(mdev, data);
210 for (i = 0; i < data->num_ports; i++) {
211 memset(&uart, 0, sizeof(struct uart_8250_port));
212 spin_lock_init(&uart.port.lock);
214 uart.port.flags = UPF_SKIP_TEST |
215 UPF_SHARE_IRQ |
216 UPF_BOOT_AUTOCONF |
217 UPF_IOREMAP;
218 uart.port.iotype = UPIO_MEM;
219 uart.port.uartclk = men_lookup_uartclk(mdev);
220 uart.port.irq = mcb_get_irq(mdev);
221 uart.port.mapbase = (unsigned long) mem->start
222 + data->offset[i];
224 /* ok, register the port */
225 res = serial8250_register_8250_port(&uart);
226 if (res < 0) {
227 dev_err(&mdev->dev, "unable to register UART port\n");
228 return res;
231 data->line[i] = res;
232 dev_info(&mdev->dev, "found MCB UART: ttyS%d\n", data->line[i]);
235 return 0;
238 static void serial_8250_men_mcb_remove(struct mcb_device *mdev)
240 int i;
241 struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev);
243 if (!data)
244 return;
246 for (i = 0; i < data->num_ports; i++)
247 serial8250_unregister_port(data->line[i]);
250 static const struct mcb_device_id serial_8250_men_mcb_ids[] = {
251 { .device = MEN_UART_ID_Z025 },
252 { .device = MEN_UART_ID_Z057 },
253 { .device = MEN_UART_ID_Z125 },
256 MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids);
258 static struct mcb_driver mcb_driver = {
259 .driver = {
260 .name = "8250_men_mcb",
262 .probe = serial_8250_men_mcb_probe,
263 .remove = serial_8250_men_mcb_remove,
264 .id_table = serial_8250_men_mcb_ids,
266 module_mcb_driver(mcb_driver);
268 MODULE_LICENSE("GPL v2");
269 MODULE_DESCRIPTION("MEN 8250 UART driver");
270 MODULE_AUTHOR("Michael Moese <michael.moese@men.de");
271 MODULE_ALIAS("mcb:16z125");
272 MODULE_ALIAS("mcb:16z025");
273 MODULE_ALIAS("mcb:16z057");
274 MODULE_IMPORT_NS("MCB");