Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: serial: ip22zilog: Use platform device for probing

After commit 84a9582fd203 ("serial: core: Start managing serial controllers
to enable runtime PM") serial drivers need to provide a device in
struct uart_port.dev otherwise an oops happens. To fix this issue
for ip22zilog driver switch driver to a platform driver and setup
the serial device in sgi-ip22 code.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Link: https://lore.kernel.org/r/20250725134018.136113-1-tsbogend@alpha.franken.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Thomas Bogendoerfer and committed by
Greg Kroah-Hartman
3fc36ae6 96c08ff8

+179 -213
+32
arch/mips/sgi-ip22/ip22-platform.c
··· 221 221 } 222 222 223 223 device_initcall(sgi_ds1286_devinit); 224 + 225 + #define SGI_ZILOG_BASE (HPC3_CHIP0_BASE + \ 226 + offsetof(struct hpc3_regs, pbus_extregs[6]) + \ 227 + offsetof(struct sgioc_regs, uart)) 228 + 229 + static struct resource sgi_zilog_resources[] = { 230 + { 231 + .start = SGI_ZILOG_BASE, 232 + .end = SGI_ZILOG_BASE + 15, 233 + .flags = IORESOURCE_MEM 234 + }, 235 + { 236 + .start = SGI_SERIAL_IRQ, 237 + .end = SGI_SERIAL_IRQ, 238 + .flags = IORESOURCE_IRQ 239 + } 240 + }; 241 + 242 + static struct platform_device zilog_device = { 243 + .name = "ip22zilog", 244 + .id = 0, 245 + .num_resources = ARRAY_SIZE(sgi_zilog_resources), 246 + .resource = sgi_zilog_resources, 247 + }; 248 + 249 + 250 + static int __init sgi_zilog_devinit(void) 251 + { 252 + return platform_device_register(&zilog_device); 253 + } 254 + 255 + device_initcall(sgi_zilog_devinit);
+147 -213
drivers/tty/serial/ip22zilog.c
··· 30 30 #include <linux/console.h> 31 31 #include <linux/spinlock.h> 32 32 #include <linux/init.h> 33 + #include <linux/platform_device.h> 33 34 34 35 #include <linux/io.h> 35 36 #include <asm/irq.h> ··· 51 50 #define ZSDELAY_LONG() udelay(20) 52 51 #define ZS_WSYNC(channel) do { } while (0) 53 52 54 - #define NUM_IP22ZILOG 1 55 - #define NUM_CHANNELS (NUM_IP22ZILOG * 2) 53 + #define NUM_CHANNELS 2 54 + #define CHANNEL_B 0 55 + #define CHANNEL_A 1 56 56 57 57 #define ZS_CLOCK 3672000 /* Zilog input clock rate. */ 58 58 #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ ··· 64 62 struct uart_ip22zilog_port { 65 63 struct uart_port port; 66 64 67 - /* IRQ servicing chain. */ 68 - struct uart_ip22zilog_port *next; 69 - 70 65 /* Current values of Zilog write registers. */ 71 66 unsigned char curregs[NUM_ZSREGS]; 72 67 ··· 71 72 #define IP22ZILOG_FLAG_IS_CONS 0x00000004 72 73 #define IP22ZILOG_FLAG_IS_KGDB 0x00000008 73 74 #define IP22ZILOG_FLAG_MODEM_STATUS 0x00000010 74 - #define IP22ZILOG_FLAG_IS_CHANNEL_A 0x00000020 75 75 #define IP22ZILOG_FLAG_REGS_HELD 0x00000040 76 76 #define IP22ZILOG_FLAG_TX_STOPPED 0x00000080 77 77 #define IP22ZILOG_FLAG_TX_ACTIVE 0x00000100 ··· 82 84 unsigned char prev_status; 83 85 }; 84 86 87 + static struct uart_ip22zilog_port ip22zilog_port_table[NUM_CHANNELS]; 88 + 85 89 #define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel *)((PORT)->membase)) 86 90 #define UART_ZILOG(PORT) ((struct uart_ip22zilog_port *)(PORT)) 87 91 #define IP22ZILOG_GET_CURR_REG(PORT, REGNUM) \ ··· 93 93 #define ZS_IS_CONS(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_CONS) 94 94 #define ZS_IS_KGDB(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_KGDB) 95 95 #define ZS_WANTS_MODEM_STATUS(UP) ((UP)->flags & IP22ZILOG_FLAG_MODEM_STATUS) 96 - #define ZS_IS_CHANNEL_A(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_CHANNEL_A) 97 96 #define ZS_REGS_HELD(UP) ((UP)->flags & IP22ZILOG_FLAG_REGS_HELD) 98 97 #define ZS_TX_STOPPED(UP) ((UP)->flags & IP22ZILOG_FLAG_TX_STOPPED) 99 98 #define ZS_TX_ACTIVE(UP) ((UP)->flags & IP22ZILOG_FLAG_TX_ACTIVE) ··· 422 423 423 424 static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) 424 425 { 425 - struct uart_ip22zilog_port *up = dev_id; 426 + struct uart_ip22zilog_port *up; 427 + struct zilog_channel *channel; 428 + unsigned char r3; 429 + bool push = false; 426 430 427 - while (up) { 428 - struct zilog_channel *channel 429 - = ZILOG_CHANNEL_FROM_PORT(&up->port); 430 - unsigned char r3; 431 - bool push = false; 431 + up = &ip22zilog_port_table[CHANNEL_A]; 432 + channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 432 433 433 - uart_port_lock(&up->port); 434 - r3 = read_zsreg(channel, R3); 434 + uart_port_lock(&up->port); 435 + r3 = read_zsreg(channel, R3); 435 436 436 - /* Channel A */ 437 - if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { 438 - writeb(RES_H_IUS, &channel->control); 439 - ZSDELAY(); 440 - ZS_WSYNC(channel); 437 + /* Channel A */ 438 + if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { 439 + writeb(RES_H_IUS, &channel->control); 440 + ZSDELAY(); 441 + ZS_WSYNC(channel); 441 442 442 - if (r3 & CHARxIP) 443 - push = ip22zilog_receive_chars(up, channel); 444 - if (r3 & CHAEXT) 445 - ip22zilog_status_handle(up, channel); 446 - if (r3 & CHATxIP) 447 - ip22zilog_transmit_chars(up, channel); 448 - } 449 - uart_port_unlock(&up->port); 450 - 451 - if (push) 452 - tty_flip_buffer_push(&up->port.state->port); 453 - 454 - /* Channel B */ 455 - up = up->next; 456 - channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 457 - push = false; 458 - 459 - uart_port_lock(&up->port); 460 - if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { 461 - writeb(RES_H_IUS, &channel->control); 462 - ZSDELAY(); 463 - ZS_WSYNC(channel); 464 - 465 - if (r3 & CHBRxIP) 466 - push = ip22zilog_receive_chars(up, channel); 467 - if (r3 & CHBEXT) 468 - ip22zilog_status_handle(up, channel); 469 - if (r3 & CHBTxIP) 470 - ip22zilog_transmit_chars(up, channel); 471 - } 472 - uart_port_unlock(&up->port); 473 - 474 - if (push) 475 - tty_flip_buffer_push(&up->port.state->port); 476 - 477 - up = up->next; 443 + if (r3 & CHARxIP) 444 + push = ip22zilog_receive_chars(up, channel); 445 + if (r3 & CHAEXT) 446 + ip22zilog_status_handle(up, channel); 447 + if (r3 & CHATxIP) 448 + ip22zilog_transmit_chars(up, channel); 478 449 } 450 + uart_port_unlock(&up->port); 451 + 452 + if (push) 453 + tty_flip_buffer_push(&up->port.state->port); 454 + 455 + /* Channel B */ 456 + up = &ip22zilog_port_table[CHANNEL_B]; 457 + channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 458 + push = false; 459 + 460 + uart_port_lock(&up->port); 461 + if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { 462 + writeb(RES_H_IUS, &channel->control); 463 + ZSDELAY(); 464 + ZS_WSYNC(channel); 465 + 466 + if (r3 & CHBRxIP) 467 + push = ip22zilog_receive_chars(up, channel); 468 + if (r3 & CHBEXT) 469 + ip22zilog_status_handle(up, channel); 470 + if (r3 & CHBTxIP) 471 + ip22zilog_transmit_chars(up, channel); 472 + } 473 + uart_port_unlock(&up->port); 474 + 475 + if (push) 476 + tty_flip_buffer_push(&up->port.state->port); 479 477 480 478 return IRQ_HANDLED; 481 479 } ··· 688 692 udelay(100); 689 693 } 690 694 691 - if (!ZS_IS_CHANNEL_A(up)) { 692 - up++; 693 - channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 694 - } 695 + up = &ip22zilog_port_table[CHANNEL_A]; 696 + channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 697 + 695 698 write_zsreg(channel, R9, FHWRES); 696 699 ZSDELAY_LONG(); 697 700 (void) read_zsreg(channel, R0); 698 701 699 702 up->flags |= IP22ZILOG_FLAG_RESET_DONE; 700 - up->next->flags |= IP22ZILOG_FLAG_RESET_DONE; 703 + up = &ip22zilog_port_table[CHANNEL_B]; 704 + up->flags |= IP22ZILOG_FLAG_RESET_DONE; 701 705 } 702 706 703 707 static void __ip22zilog_startup(struct uart_ip22zilog_port *up) ··· 938 942 .verify_port = ip22zilog_verify_port, 939 943 }; 940 944 941 - static struct uart_ip22zilog_port *ip22zilog_port_table; 942 - static struct zilog_layout **ip22zilog_chip_regs; 943 - 944 - static struct uart_ip22zilog_port *ip22zilog_irq_chain; 945 - static int zilog_irq = -1; 946 - 947 - static void * __init alloc_one_table(unsigned long size) 948 - { 949 - return kzalloc(size, GFP_KERNEL); 950 - } 951 - 952 - static void __init ip22zilog_alloc_tables(void) 953 - { 954 - ip22zilog_port_table = (struct uart_ip22zilog_port *) 955 - alloc_one_table(NUM_CHANNELS * sizeof(struct uart_ip22zilog_port)); 956 - ip22zilog_chip_regs = (struct zilog_layout **) 957 - alloc_one_table(NUM_IP22ZILOG * sizeof(struct zilog_layout *)); 958 - 959 - if (ip22zilog_port_table == NULL || ip22zilog_chip_regs == NULL) { 960 - panic("IP22-Zilog: Cannot allocate IP22-Zilog tables."); 961 - } 962 - } 963 - 964 - /* Get the address of the registers for IP22-Zilog instance CHIP. */ 965 - static struct zilog_layout * __init get_zs(int chip) 966 - { 967 - unsigned long base; 968 - 969 - if (chip < 0 || chip >= NUM_IP22ZILOG) { 970 - panic("IP22-Zilog: Illegal chip number %d in get_zs.", chip); 971 - } 972 - 973 - /* Not probe-able, hard code it. */ 974 - base = (unsigned long) &sgioc->uart; 975 - 976 - zilog_irq = SGI_SERIAL_IRQ; 977 - request_mem_region(base, 8, "IP22-Zilog"); 978 - 979 - return (struct zilog_layout *) base; 980 - } 981 - 982 945 #define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */ 983 946 984 947 #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE ··· 1025 1070 #endif 1026 1071 }; 1027 1072 1028 - static void __init ip22zilog_prepare(void) 1073 + static void __init ip22zilog_prepare(struct uart_ip22zilog_port *up) 1029 1074 { 1030 1075 unsigned char sysrq_on = IS_ENABLED(CONFIG_SERIAL_IP22_ZILOG_CONSOLE); 1031 - struct uart_ip22zilog_port *up; 1032 - struct zilog_layout *rp; 1033 - int channel, chip; 1076 + int brg; 1034 1077 1035 - /* 1036 - * Temporary fix. 1037 - */ 1038 - for (channel = 0; channel < NUM_CHANNELS; channel++) 1039 - spin_lock_init(&ip22zilog_port_table[channel].port.lock); 1078 + spin_lock_init(&up->port.lock); 1040 1079 1041 - ip22zilog_irq_chain = &ip22zilog_port_table[NUM_CHANNELS - 1]; 1042 - up = &ip22zilog_port_table[0]; 1043 - for (channel = NUM_CHANNELS - 1 ; channel > 0; channel--) 1044 - up[channel].next = &up[channel - 1]; 1045 - up[channel].next = NULL; 1080 + up->port.iotype = UPIO_MEM; 1081 + up->port.uartclk = ZS_CLOCK; 1082 + up->port.fifosize = 1; 1083 + up->port.has_sysrq = sysrq_on; 1084 + up->port.ops = &ip22zilog_pops; 1085 + up->port.type = PORT_IP22ZILOG; 1046 1086 1047 - for (chip = 0; chip < NUM_IP22ZILOG; chip++) { 1048 - if (!ip22zilog_chip_regs[chip]) { 1049 - ip22zilog_chip_regs[chip] = rp = get_zs(chip); 1050 - 1051 - up[(chip * 2) + 0].port.membase = (char *) &rp->channelB; 1052 - up[(chip * 2) + 1].port.membase = (char *) &rp->channelA; 1053 - 1054 - /* In theory mapbase is the physical address ... */ 1055 - up[(chip * 2) + 0].port.mapbase = 1056 - (unsigned long) ioremap((unsigned long) &rp->channelB, 8); 1057 - up[(chip * 2) + 1].port.mapbase = 1058 - (unsigned long) ioremap((unsigned long) &rp->channelA, 8); 1059 - } 1060 - 1061 - /* Channel A */ 1062 - up[(chip * 2) + 0].port.iotype = UPIO_MEM; 1063 - up[(chip * 2) + 0].port.irq = zilog_irq; 1064 - up[(chip * 2) + 0].port.uartclk = ZS_CLOCK; 1065 - up[(chip * 2) + 0].port.fifosize = 1; 1066 - up[(chip * 2) + 0].port.has_sysrq = sysrq_on; 1067 - up[(chip * 2) + 0].port.ops = &ip22zilog_pops; 1068 - up[(chip * 2) + 0].port.type = PORT_IP22ZILOG; 1069 - up[(chip * 2) + 0].port.flags = 0; 1070 - up[(chip * 2) + 0].port.line = (chip * 2) + 0; 1071 - up[(chip * 2) + 0].flags = 0; 1072 - 1073 - /* Channel B */ 1074 - up[(chip * 2) + 1].port.iotype = UPIO_MEM; 1075 - up[(chip * 2) + 1].port.irq = zilog_irq; 1076 - up[(chip * 2) + 1].port.uartclk = ZS_CLOCK; 1077 - up[(chip * 2) + 1].port.fifosize = 1; 1078 - up[(chip * 2) + 1].port.has_sysrq = sysrq_on; 1079 - up[(chip * 2) + 1].port.ops = &ip22zilog_pops; 1080 - up[(chip * 2) + 1].port.type = PORT_IP22ZILOG; 1081 - up[(chip * 2) + 1].port.line = (chip * 2) + 1; 1082 - up[(chip * 2) + 1].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A; 1083 - } 1084 - 1085 - for (channel = 0; channel < NUM_CHANNELS; channel++) { 1086 - struct uart_ip22zilog_port *up = &ip22zilog_port_table[channel]; 1087 - int brg; 1088 - 1089 - /* Normal serial TTY. */ 1090 - up->parity_mask = 0xff; 1091 - up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB; 1092 - up->curregs[R4] = PAR_EVEN | X16CLK | SB1; 1093 - up->curregs[R3] = RxENAB | Rx8; 1094 - up->curregs[R5] = TxENAB | Tx8; 1095 - up->curregs[R9] = NV | MIE; 1096 - up->curregs[R10] = NRZ; 1097 - up->curregs[R11] = TCBR | RCBR; 1098 - brg = BPS_TO_BRG(9600, ZS_CLOCK / ZS_CLOCK_DIVISOR); 1099 - up->curregs[R12] = (brg & 0xff); 1100 - up->curregs[R13] = (brg >> 8) & 0xff; 1101 - up->curregs[R14] = BRENAB; 1102 - } 1087 + /* Normal serial TTY. */ 1088 + up->parity_mask = 0xff; 1089 + up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB; 1090 + up->curregs[R4] = PAR_EVEN | X16CLK | SB1; 1091 + up->curregs[R3] = RxENAB | Rx8; 1092 + up->curregs[R5] = TxENAB | Tx8; 1093 + up->curregs[R9] = NV | MIE; 1094 + up->curregs[R10] = NRZ; 1095 + up->curregs[R11] = TCBR | RCBR; 1096 + brg = BPS_TO_BRG(9600, ZS_CLOCK / ZS_CLOCK_DIVISOR); 1097 + up->curregs[R12] = (brg & 0xff); 1098 + up->curregs[R13] = (brg >> 8) & 0xff; 1099 + up->curregs[R14] = BRENAB; 1103 1100 } 1104 1101 1105 - static int __init ip22zilog_ports_init(void) 1102 + static int ip22zilog_probe(struct platform_device *pdev) 1106 1103 { 1107 - int ret; 1104 + struct uart_ip22zilog_port *up; 1105 + char __iomem *membase; 1106 + struct resource *res; 1107 + int irq; 1108 + int i; 1108 1109 1109 - printk(KERN_INFO "Serial: IP22 Zilog driver (%d chips).\n", NUM_IP22ZILOG); 1110 + up = &ip22zilog_port_table[CHANNEL_B]; 1111 + if (up->port.dev) 1112 + return -ENOSPC; 1110 1113 1111 - ip22zilog_prepare(); 1114 + irq = platform_get_irq(pdev, 0); 1115 + if (irq < 0) 1116 + return irq; 1112 1117 1113 - if (request_irq(zilog_irq, ip22zilog_interrupt, 0, 1114 - "IP22-Zilog", ip22zilog_irq_chain)) { 1118 + membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 1119 + if (IS_ERR(membase)) 1120 + return PTR_ERR(membase); 1121 + 1122 + ip22zilog_prepare(up); 1123 + 1124 + up->port.mapbase = res->start + offsetof(struct zilog_layout, channelB); 1125 + up->port.membase = membase + offsetof(struct zilog_layout, channelB); 1126 + up->port.line = 0; 1127 + up->port.dev = &pdev->dev; 1128 + up->port.irq = irq; 1129 + 1130 + up = &ip22zilog_port_table[CHANNEL_A]; 1131 + ip22zilog_prepare(up); 1132 + 1133 + up->port.mapbase = res->start + offsetof(struct zilog_layout, channelA); 1134 + up->port.membase = membase + offsetof(struct zilog_layout, channelA); 1135 + up->port.line = 1; 1136 + up->port.dev = &pdev->dev; 1137 + up->port.irq = irq; 1138 + 1139 + if (request_irq(irq, ip22zilog_interrupt, 0, 1140 + "IP22-Zilog", NULL)) { 1115 1141 panic("IP22-Zilog: Unable to register zs interrupt handler.\n"); 1116 1142 } 1117 1143 1118 - ret = uart_register_driver(&ip22zilog_reg); 1119 - if (ret == 0) { 1120 - int i; 1121 - 1122 - for (i = 0; i < NUM_CHANNELS; i++) { 1123 - struct uart_ip22zilog_port *up = &ip22zilog_port_table[i]; 1124 - 1125 - uart_add_one_port(&ip22zilog_reg, &up->port); 1126 - } 1127 - } 1128 - 1129 - return ret; 1130 - } 1131 - 1132 - static int __init ip22zilog_init(void) 1133 - { 1134 - /* IP22 Zilog setup is hard coded, no probing to do. */ 1135 - ip22zilog_alloc_tables(); 1136 - ip22zilog_ports_init(); 1144 + for (i = 0; i < NUM_CHANNELS; i++) 1145 + uart_add_one_port(&ip22zilog_reg, 1146 + &ip22zilog_port_table[i].port); 1137 1147 1138 1148 return 0; 1139 1149 } 1140 1150 1141 - static void __exit ip22zilog_exit(void) 1151 + static void ip22zilog_remove(struct platform_device *pdev) 1142 1152 { 1143 1153 int i; 1144 - struct uart_ip22zilog_port *up; 1145 1154 1146 1155 for (i = 0; i < NUM_CHANNELS; i++) { 1147 - up = &ip22zilog_port_table[i]; 1148 - 1149 - uart_remove_one_port(&ip22zilog_reg, &up->port); 1156 + uart_remove_one_port(&ip22zilog_reg, 1157 + &ip22zilog_port_table[i].port); 1158 + ip22zilog_port_table[i].port.dev = NULL; 1150 1159 } 1160 + } 1151 1161 1152 - /* Free IO mem */ 1153 - up = &ip22zilog_port_table[0]; 1154 - for (i = 0; i < NUM_IP22ZILOG; i++) { 1155 - if (up[(i * 2) + 0].port.mapbase) { 1156 - iounmap((void*)up[(i * 2) + 0].port.mapbase); 1157 - up[(i * 2) + 0].port.mapbase = 0; 1158 - } 1159 - if (up[(i * 2) + 1].port.mapbase) { 1160 - iounmap((void*)up[(i * 2) + 1].port.mapbase); 1161 - up[(i * 2) + 1].port.mapbase = 0; 1162 - } 1162 + static struct platform_driver ip22zilog_driver = { 1163 + .probe = ip22zilog_probe, 1164 + .remove = ip22zilog_remove, 1165 + .driver = { 1166 + .name = "ip22zilog" 1163 1167 } 1168 + }; 1164 1169 1170 + static int __init ip22zilog_init(void) 1171 + { 1172 + int ret; 1173 + 1174 + ret = uart_register_driver(&ip22zilog_reg); 1175 + if (ret) 1176 + return ret; 1177 + 1178 + ret = platform_driver_register(&ip22zilog_driver); 1179 + if (ret) 1180 + uart_unregister_driver(&ip22zilog_reg); 1181 + 1182 + return ret; 1183 + 1184 + } 1185 + 1186 + static void __exit ip22zilog_exit(void) 1187 + { 1165 1188 uart_unregister_driver(&ip22zilog_reg); 1189 + platform_driver_unregister(&ip22zilog_driver); 1166 1190 } 1167 1191 1168 1192 module_init(ip22zilog_init);