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

Configure Feed

Select the types of activity you want to include in your feed.

tty: goldfish: Introduce gf_ioread32()/gf_iowrite32()

The goldfish TTY device was clearly defined as having little-endian
registers, but the switch to __raw_{read,write}l(() broke its driver
when running on big-endian kernels (if anyone ever tried this).

The m68k qemu implementation got this wrong, and assumed native-endian
registers. While this is a bug in qemu, it is probably impossible to
fix that since there is no way of knowing which other operating systems
have started relying on that bug over the years.

Hence revert commit da31de35cd2f ("tty: goldfish: use
__raw_writel()/__raw_readl()", and define gf_ioread32()/gf_iowrite32()
to be able to use accessors defined by the architecture.

Cc: stable@vger.kernel.org # v5.11+
Fixes: da31de35cd2fb78f ("tty: goldfish: use __raw_writel()/__raw_readl()")
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Link: https://lore.kernel.org/r/20220406201523.243733-2-laurent@vivier.eu
[geert: Add rationale based on Arnd's comments]
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>

authored by

Laurent Vivier and committed by
Geert Uytterhoeven
2e2ac4a3 31231092

+21 -14
+10 -10
drivers/tty/goldfish.c
··· 61 61 spin_lock_irqsave(&qtty->lock, irq_flags); 62 62 gf_write_ptr((void *)address, base + GOLDFISH_TTY_REG_DATA_PTR, 63 63 base + GOLDFISH_TTY_REG_DATA_PTR_HIGH); 64 - __raw_writel(count, base + GOLDFISH_TTY_REG_DATA_LEN); 64 + gf_iowrite32(count, base + GOLDFISH_TTY_REG_DATA_LEN); 65 65 66 66 if (is_write) 67 - __raw_writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, 67 + gf_iowrite32(GOLDFISH_TTY_CMD_WRITE_BUFFER, 68 68 base + GOLDFISH_TTY_REG_CMD); 69 69 else 70 - __raw_writel(GOLDFISH_TTY_CMD_READ_BUFFER, 70 + gf_iowrite32(GOLDFISH_TTY_CMD_READ_BUFFER, 71 71 base + GOLDFISH_TTY_REG_CMD); 72 72 73 73 spin_unlock_irqrestore(&qtty->lock, irq_flags); ··· 142 142 unsigned char *buf; 143 143 u32 count; 144 144 145 - count = __raw_readl(base + GOLDFISH_TTY_REG_BYTES_READY); 145 + count = gf_ioread32(base + GOLDFISH_TTY_REG_BYTES_READY); 146 146 if (count == 0) 147 147 return IRQ_NONE; 148 148 ··· 159 159 { 160 160 struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, 161 161 port); 162 - __raw_writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD); 162 + gf_iowrite32(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD); 163 163 return 0; 164 164 } 165 165 ··· 167 167 { 168 168 struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, 169 169 port); 170 - __raw_writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD); 170 + gf_iowrite32(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD); 171 171 } 172 172 173 173 static int goldfish_tty_open(struct tty_struct *tty, struct file *filp) ··· 202 202 { 203 203 struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; 204 204 void __iomem *base = qtty->base; 205 - return __raw_readl(base + GOLDFISH_TTY_REG_BYTES_READY); 205 + return gf_ioread32(base + GOLDFISH_TTY_REG_BYTES_READY); 206 206 } 207 207 208 208 static void goldfish_tty_console_write(struct console *co, const char *b, ··· 355 355 * on Ranchu emulator (qemu2) returns 1 here and 356 356 * driver will use physical addresses. 357 357 */ 358 - qtty->version = __raw_readl(base + GOLDFISH_TTY_REG_VERSION); 358 + qtty->version = gf_ioread32(base + GOLDFISH_TTY_REG_VERSION); 359 359 360 360 /* 361 361 * Goldfish TTY device on Ranchu emulator (qemu2) ··· 374 374 } 375 375 } 376 376 377 - __raw_writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD); 377 + gf_iowrite32(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD); 378 378 379 379 ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED, 380 380 "goldfish_tty", qtty); ··· 436 436 #ifdef CONFIG_GOLDFISH_TTY_EARLY_CONSOLE 437 437 static void gf_early_console_putchar(struct uart_port *port, unsigned char ch) 438 438 { 439 - __raw_writel(ch, port->membase); 439 + gf_iowrite32(ch, port->membase); 440 440 } 441 441 442 442 static void gf_early_write(struct console *con, const char *s, unsigned int n)
+11 -4
include/linux/goldfish.h
··· 8 8 9 9 /* Helpers for Goldfish virtual platform */ 10 10 11 + #ifndef gf_ioread32 12 + #define gf_ioread32 ioread32 13 + #endif 14 + #ifndef gf_iowrite32 15 + #define gf_iowrite32 iowrite32 16 + #endif 17 + 11 18 static inline void gf_write_ptr(const void *ptr, void __iomem *portl, 12 19 void __iomem *porth) 13 20 { 14 21 const unsigned long addr = (unsigned long)ptr; 15 22 16 - __raw_writel(lower_32_bits(addr), portl); 23 + gf_iowrite32(lower_32_bits(addr), portl); 17 24 #ifdef CONFIG_64BIT 18 - __raw_writel(upper_32_bits(addr), porth); 25 + gf_iowrite32(upper_32_bits(addr), porth); 19 26 #endif 20 27 } 21 28 ··· 30 23 void __iomem *portl, 31 24 void __iomem *porth) 32 25 { 33 - __raw_writel(lower_32_bits(addr), portl); 26 + gf_iowrite32(lower_32_bits(addr), portl); 34 27 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 35 - __raw_writel(upper_32_bits(addr), porth); 28 + gf_iowrite32(upper_32_bits(addr), porth); 36 29 #endif 37 30 } 38 31