1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/device.h>
3 #include <linux/kernel.h>
4 #include <linux/module.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:
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)
47 struct serial_8250_men_mcb_data
{
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 */
64 dev_info(&mdev
->dev
, "%s on board %s\n",
67 if (strncmp(mdev
->bus
->name
, "F075", 4) == 0)
69 else if (strncmp(mdev
->bus
->name
, "F216", 4) == 0)
71 else if (strncmp(mdev
->bus
->name
, "F210", 4) == 0)
73 else if (strstr(mdev
->bus
->name
, "215"))
77 "board not detected, using default uartclk\n");
84 static int read_uarts_available_from_register(struct resource
*mem_res
,
90 if (!request_mem_region(mem_res
->start
+ MEN_Z025_REGISTER_OFFSET
,
91 MEM_UART_REGISTER_SIZE
, KBUILD_MODNAME
)) {
95 mem
= ioremap(mem_res
->start
+ MEN_Z025_REGISTER_OFFSET
,
96 MEM_UART_REGISTER_SIZE
);
98 release_mem_region(mem_res
->start
+ MEN_Z025_REGISTER_OFFSET
,
99 MEM_UART_REGISTER_SIZE
);
103 reg_value
= MEN_READ_REGISTER(mem
);
107 release_mem_region(mem_res
->start
+ MEN_Z025_REGISTER_OFFSET
,
108 MEM_UART_REGISTER_SIZE
);
110 *uarts_available
= reg_value
>> 4;
115 static int read_serial_data(struct mcb_device
*mdev
,
116 struct resource
*mem_res
,
117 struct serial_8250_men_mcb_data
*serial_data
)
125 res
= read_uarts_available_from_register(mem_res
, &uarts_available
);
129 for (i
= 0; i
< MAX_PORTS
; i
++) {
131 switch (uarts_available
& mask
) {
133 serial_data
->offset
[count
] = MEN_UART1_OFFSET
;
137 serial_data
->offset
[count
] = MEN_UART2_OFFSET
;
141 serial_data
->offset
[count
] = MEN_UART3_OFFSET
;
145 serial_data
->offset
[count
] = MEN_UART4_OFFSET
;
153 if (count
<= 0 || count
> MAX_PORTS
) {
154 dev_err(&mdev
->dev
, "unexpected number of ports: %u\n",
159 serial_data
->num_ports
= count
;
164 static int init_serial_data(struct mcb_device
*mdev
,
165 struct resource
*mem_res
,
166 struct serial_8250_men_mcb_data
*serial_data
)
169 case MEN_UART_ID_Z125
:
170 serial_data
->num_ports
= 1;
171 serial_data
->offset
[0] = 0;
173 case MEN_UART_ID_Z025
:
174 case MEN_UART_ID_Z057
:
175 return read_serial_data(mdev
, mem_res
, serial_data
);
177 dev_err(&mdev
->dev
, "no supported device!\n");
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
;
191 mem
= mcb_get_resource(mdev
, IORESOURCE_MEM
);
195 data
= devm_kzalloc(&mdev
->dev
,
196 sizeof(struct serial_8250_men_mcb_data
),
201 res
= init_serial_data(mdev
, mem
, data
);
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
|
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
224 /* ok, register the port */
225 res
= serial8250_register_8250_port(&uart
);
227 dev_err(&mdev
->dev
, "unable to register UART port\n");
232 dev_info(&mdev
->dev
, "found MCB UART: ttyS%d\n", data
->line
[i
]);
238 static void serial_8250_men_mcb_remove(struct mcb_device
*mdev
)
241 struct serial_8250_men_mcb_data
*data
= mcb_get_drvdata(mdev
);
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
= {
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");