| .. | .. |
|---|
| 24 | 24 | #include <linux/console.h> |
|---|
| 25 | 25 | #include <linux/sysrq.h> |
|---|
| 26 | 26 | #include <linux/device.h> |
|---|
| 27 | | -#include <linux/bootmem.h> |
|---|
| 27 | +#include <linux/memblock.h> |
|---|
| 28 | 28 | #include <linux/dma-mapping.h> |
|---|
| 29 | 29 | #include <linux/fs_uart_pd.h> |
|---|
| 30 | 30 | #include <linux/of_address.h> |
|---|
| 31 | 31 | #include <linux/of_irq.h> |
|---|
| 32 | 32 | #include <linux/of_platform.h> |
|---|
| 33 | | -#include <linux/gpio.h> |
|---|
| 34 | | -#include <linux/of_gpio.h> |
|---|
| 33 | +#include <linux/gpio/consumer.h> |
|---|
| 35 | 34 | #include <linux/clk.h> |
|---|
| 36 | 35 | |
|---|
| 37 | 36 | #include <asm/io.h> |
|---|
| .. | .. |
|---|
| 39 | 38 | #include <asm/delay.h> |
|---|
| 40 | 39 | #include <asm/fs_pd.h> |
|---|
| 41 | 40 | #include <asm/udbg.h> |
|---|
| 42 | | - |
|---|
| 43 | | -#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
|---|
| 44 | | -#define SUPPORT_SYSRQ |
|---|
| 45 | | -#endif |
|---|
| 46 | 41 | |
|---|
| 47 | 42 | #include <linux/serial_core.h> |
|---|
| 48 | 43 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 92 | 87 | struct uart_cpm_port *pinfo = |
|---|
| 93 | 88 | container_of(port, struct uart_cpm_port, port); |
|---|
| 94 | 89 | |
|---|
| 95 | | - if (pinfo->gpios[GPIO_RTS] >= 0) |
|---|
| 96 | | - gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS)); |
|---|
| 90 | + if (pinfo->gpios[GPIO_RTS]) |
|---|
| 91 | + gpiod_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS)); |
|---|
| 97 | 92 | |
|---|
| 98 | | - if (pinfo->gpios[GPIO_DTR] >= 0) |
|---|
| 99 | | - gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR)); |
|---|
| 93 | + if (pinfo->gpios[GPIO_DTR]) |
|---|
| 94 | + gpiod_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR)); |
|---|
| 100 | 95 | } |
|---|
| 101 | 96 | |
|---|
| 102 | 97 | static unsigned int cpm_uart_get_mctrl(struct uart_port *port) |
|---|
| .. | .. |
|---|
| 105 | 100 | container_of(port, struct uart_cpm_port, port); |
|---|
| 106 | 101 | unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; |
|---|
| 107 | 102 | |
|---|
| 108 | | - if (pinfo->gpios[GPIO_CTS] >= 0) { |
|---|
| 109 | | - if (gpio_get_value(pinfo->gpios[GPIO_CTS])) |
|---|
| 103 | + if (pinfo->gpios[GPIO_CTS]) { |
|---|
| 104 | + if (gpiod_get_value(pinfo->gpios[GPIO_CTS])) |
|---|
| 110 | 105 | mctrl &= ~TIOCM_CTS; |
|---|
| 111 | 106 | } |
|---|
| 112 | 107 | |
|---|
| 113 | | - if (pinfo->gpios[GPIO_DSR] >= 0) { |
|---|
| 114 | | - if (gpio_get_value(pinfo->gpios[GPIO_DSR])) |
|---|
| 108 | + if (pinfo->gpios[GPIO_DSR]) { |
|---|
| 109 | + if (gpiod_get_value(pinfo->gpios[GPIO_DSR])) |
|---|
| 115 | 110 | mctrl &= ~TIOCM_DSR; |
|---|
| 116 | 111 | } |
|---|
| 117 | 112 | |
|---|
| 118 | | - if (pinfo->gpios[GPIO_DCD] >= 0) { |
|---|
| 119 | | - if (gpio_get_value(pinfo->gpios[GPIO_DCD])) |
|---|
| 113 | + if (pinfo->gpios[GPIO_DCD]) { |
|---|
| 114 | + if (gpiod_get_value(pinfo->gpios[GPIO_DCD])) |
|---|
| 120 | 115 | mctrl &= ~TIOCM_CAR; |
|---|
| 121 | 116 | } |
|---|
| 122 | 117 | |
|---|
| 123 | | - if (pinfo->gpios[GPIO_RI] >= 0) { |
|---|
| 124 | | - if (!gpio_get_value(pinfo->gpios[GPIO_RI])) |
|---|
| 118 | + if (pinfo->gpios[GPIO_RI]) { |
|---|
| 119 | + if (!gpiod_get_value(pinfo->gpios[GPIO_RI])) |
|---|
| 125 | 120 | mctrl |= TIOCM_RNG; |
|---|
| 126 | 121 | } |
|---|
| 127 | 122 | |
|---|
| .. | .. |
|---|
| 347 | 342 | /* ASSUMPTION: it contains nothing valid */ |
|---|
| 348 | 343 | i = 0; |
|---|
| 349 | 344 | } |
|---|
| 350 | | -#ifdef SUPPORT_SYSRQ |
|---|
| 351 | 345 | port->sysrq = 0; |
|---|
| 352 | | -#endif |
|---|
| 353 | 346 | goto error_return; |
|---|
| 354 | 347 | } |
|---|
| 355 | 348 | |
|---|
| .. | .. |
|---|
| 576 | 569 | /* |
|---|
| 577 | 570 | * Set up parity check flag |
|---|
| 578 | 571 | */ |
|---|
| 579 | | -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
|---|
| 580 | | - |
|---|
| 581 | 572 | port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); |
|---|
| 582 | 573 | if (termios->c_iflag & INPCK) |
|---|
| 583 | 574 | port->read_status_mask |= BD_SC_FR | BD_SC_PR; |
|---|
| .. | .. |
|---|
| 1147 | 1138 | { |
|---|
| 1148 | 1139 | const u32 *data; |
|---|
| 1149 | 1140 | void __iomem *mem, *pram; |
|---|
| 1141 | + struct device *dev = pinfo->port.dev; |
|---|
| 1150 | 1142 | int len; |
|---|
| 1151 | 1143 | int ret; |
|---|
| 1152 | 1144 | int i; |
|---|
| .. | .. |
|---|
| 1160 | 1152 | if (!pinfo->clk) { |
|---|
| 1161 | 1153 | data = of_get_property(np, "fsl,cpm-brg", &len); |
|---|
| 1162 | 1154 | if (!data || len != 4) { |
|---|
| 1163 | | - printk(KERN_ERR "CPM UART %s has no/invalid " |
|---|
| 1164 | | - "fsl,cpm-brg property.\n", np->name); |
|---|
| 1155 | + printk(KERN_ERR "CPM UART %pOFn has no/invalid " |
|---|
| 1156 | + "fsl,cpm-brg property.\n", np); |
|---|
| 1165 | 1157 | return -EINVAL; |
|---|
| 1166 | 1158 | } |
|---|
| 1167 | 1159 | pinfo->brg = *data; |
|---|
| .. | .. |
|---|
| 1169 | 1161 | |
|---|
| 1170 | 1162 | data = of_get_property(np, "fsl,cpm-command", &len); |
|---|
| 1171 | 1163 | if (!data || len != 4) { |
|---|
| 1172 | | - printk(KERN_ERR "CPM UART %s has no/invalid " |
|---|
| 1173 | | - "fsl,cpm-command property.\n", np->name); |
|---|
| 1164 | + printk(KERN_ERR "CPM UART %pOFn has no/invalid " |
|---|
| 1165 | + "fsl,cpm-command property.\n", np); |
|---|
| 1174 | 1166 | return -EINVAL; |
|---|
| 1175 | 1167 | } |
|---|
| 1176 | 1168 | pinfo->command = *data; |
|---|
| .. | .. |
|---|
| 1206 | 1198 | pinfo->port.uartclk = ppc_proc_freq; |
|---|
| 1207 | 1199 | pinfo->port.mapbase = (unsigned long)mem; |
|---|
| 1208 | 1200 | pinfo->port.type = PORT_CPM; |
|---|
| 1209 | | - pinfo->port.ops = &cpm_uart_pops, |
|---|
| 1201 | + pinfo->port.ops = &cpm_uart_pops; |
|---|
| 1202 | + pinfo->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_CPM_CONSOLE); |
|---|
| 1210 | 1203 | pinfo->port.iotype = UPIO_MEM; |
|---|
| 1211 | 1204 | pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; |
|---|
| 1212 | 1205 | spin_lock_init(&pinfo->port.lock); |
|---|
| .. | .. |
|---|
| 1218 | 1211 | } |
|---|
| 1219 | 1212 | |
|---|
| 1220 | 1213 | for (i = 0; i < NUM_GPIOS; i++) { |
|---|
| 1221 | | - int gpio; |
|---|
| 1214 | + struct gpio_desc *gpiod; |
|---|
| 1222 | 1215 | |
|---|
| 1223 | | - pinfo->gpios[i] = -1; |
|---|
| 1216 | + pinfo->gpios[i] = NULL; |
|---|
| 1224 | 1217 | |
|---|
| 1225 | | - gpio = of_get_gpio(np, i); |
|---|
| 1218 | + gpiod = devm_gpiod_get_index_optional(dev, NULL, i, GPIOD_ASIS); |
|---|
| 1226 | 1219 | |
|---|
| 1227 | | - if (gpio_is_valid(gpio)) { |
|---|
| 1228 | | - ret = gpio_request(gpio, "cpm_uart"); |
|---|
| 1229 | | - if (ret) { |
|---|
| 1230 | | - pr_err("can't request gpio #%d: %d\n", i, ret); |
|---|
| 1231 | | - continue; |
|---|
| 1232 | | - } |
|---|
| 1220 | + if (IS_ERR(gpiod)) { |
|---|
| 1221 | + ret = PTR_ERR(gpiod); |
|---|
| 1222 | + goto out_irq; |
|---|
| 1223 | + } |
|---|
| 1224 | + |
|---|
| 1225 | + if (gpiod) { |
|---|
| 1233 | 1226 | if (i == GPIO_RTS || i == GPIO_DTR) |
|---|
| 1234 | | - ret = gpio_direction_output(gpio, 0); |
|---|
| 1227 | + ret = gpiod_direction_output(gpiod, 0); |
|---|
| 1235 | 1228 | else |
|---|
| 1236 | | - ret = gpio_direction_input(gpio); |
|---|
| 1229 | + ret = gpiod_direction_input(gpiod); |
|---|
| 1237 | 1230 | if (ret) { |
|---|
| 1238 | 1231 | pr_err("can't set direction for gpio #%d: %d\n", |
|---|
| 1239 | 1232 | i, ret); |
|---|
| 1240 | | - gpio_free(gpio); |
|---|
| 1241 | 1233 | continue; |
|---|
| 1242 | 1234 | } |
|---|
| 1243 | | - pinfo->gpios[i] = gpio; |
|---|
| 1235 | + pinfo->gpios[i] = gpiod; |
|---|
| 1244 | 1236 | } |
|---|
| 1245 | 1237 | } |
|---|
| 1246 | 1238 | |
|---|
| .. | .. |
|---|
| 1250 | 1242 | |
|---|
| 1251 | 1243 | return cpm_uart_request_port(&pinfo->port); |
|---|
| 1252 | 1244 | |
|---|
| 1245 | +out_irq: |
|---|
| 1246 | + irq_dispose_mapping(pinfo->port.irq); |
|---|
| 1253 | 1247 | out_pram: |
|---|
| 1254 | 1248 | cpm_uart_unmap_pram(pinfo, pram); |
|---|
| 1255 | 1249 | out_mem: |
|---|
| .. | .. |
|---|
| 1269 | 1263 | { |
|---|
| 1270 | 1264 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; |
|---|
| 1271 | 1265 | unsigned long flags; |
|---|
| 1272 | | - int nolock = oops_in_progress; |
|---|
| 1273 | 1266 | |
|---|
| 1274 | | - if (unlikely(nolock)) { |
|---|
| 1267 | + if (unlikely(oops_in_progress)) { |
|---|
| 1275 | 1268 | local_irq_save(flags); |
|---|
| 1276 | | - } else { |
|---|
| 1277 | | - spin_lock_irqsave(&pinfo->port.lock, flags); |
|---|
| 1278 | | - } |
|---|
| 1279 | | - |
|---|
| 1280 | | - cpm_uart_early_write(pinfo, s, count, true); |
|---|
| 1281 | | - |
|---|
| 1282 | | - if (unlikely(nolock)) { |
|---|
| 1269 | + cpm_uart_early_write(pinfo, s, count, true); |
|---|
| 1283 | 1270 | local_irq_restore(flags); |
|---|
| 1284 | 1271 | } else { |
|---|
| 1272 | + spin_lock_irqsave(&pinfo->port.lock, flags); |
|---|
| 1273 | + cpm_uart_early_write(pinfo, s, count, true); |
|---|
| 1285 | 1274 | spin_unlock_irqrestore(&pinfo->port.lock, flags); |
|---|
| 1286 | 1275 | } |
|---|
| 1287 | 1276 | } |
|---|
| .. | .. |
|---|
| 1380 | 1369 | |
|---|
| 1381 | 1370 | static int __init cpm_uart_console_init(void) |
|---|
| 1382 | 1371 | { |
|---|
| 1372 | + cpm_muram_init(); |
|---|
| 1383 | 1373 | register_console(&cpm_scc_uart_console); |
|---|
| 1384 | 1374 | return 0; |
|---|
| 1385 | 1375 | } |
|---|