From 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 2 Sep 2026 15:31:14 -0700 Subject: treewide: refresh kmalloc_obj() conversions This is another run of the Coccinelle script for converting kmalloc() family of allocations to kmalloc_obj() via the existing rules in scripts/coccinelle/api/kmalloc_objs.cocci This catches both the set of kmalloc() uses added since the first kmalloc_obj() conversions in v7.0 and adds a large group missed in the first pass due to Coccinelle not interacting well with the cleanup.h scoped_...() family of macros[1]. I worked around this with spatch's "--macro-file" argument to a file with all the scoped_...() macros mapped to Coccinelle's YACFE_ITERATOR[2] as that was the closest viable control flow indicator I could find. Build tested allmodconfig on x86, arm64, arm, loongarch, mips, powerpc, riscv, and s390 with no new warnings. Link: https://lore.kernel.org/lkml/202609021314.8A9C0B8@keescook/ [1] Link: https://github.com/coccinelle/coccinelle/blob/master/standard.h [2] Signed-off-by: Kees Cook --- arch/arm/mach-omap1/serial.c | 246 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 arch/arm/mach-omap1/serial.c (limited to 'arch/arm/mach-omap1/serial.c') diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c new file mode 100644 index 000000000..ffa4a9bec --- /dev/null +++ b/arch/arm/mach-omap1/serial.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * linux/arch/arm/mach-omap1/serial.c + * + * OMAP1 serial support. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "serial.h" +#include "mux.h" +#include "pm.h" +#include "soc.h" + +static struct clk * uart1_ck; +static struct clk * uart2_ck; +static struct clk * uart3_ck; + +static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, + int offset) +{ + offset <<= up->regshift; + return (unsigned int)__raw_readb(up->membase + offset); +} + +static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset, + int value) +{ + offset <<= p->regshift; + __raw_writeb(value, p->membase + offset); +} + +/* + * Internal UARTs need to be initialized for the 8250 autoconfig to work + * properly. Note that the TX watermark initialization may not be needed + * once the 8250.c watermark handling code is merged. + */ +static void __init omap_serial_reset(struct plat_serial8250_port *p) +{ + omap_serial_outp(p, UART_OMAP_MDR1, + UART_OMAP_MDR1_DISABLE); /* disable UART */ + omap_serial_outp(p, UART_OMAP_SCR, 0x08); /* TX watermark */ + omap_serial_outp(p, UART_OMAP_MDR1, + UART_OMAP_MDR1_16X_MODE); /* enable UART */ + + if (!cpu_is_omap15xx()) { + omap_serial_outp(p, UART_OMAP_SYSC, 0x01); + while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01)); + } +} + +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = OMAP1_UART1_BASE, + .irq = INT_UART1, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { + .mapbase = OMAP1_UART2_BASE, + .irq = INT_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { + .mapbase = OMAP1_UART3_BASE, + .irq = INT_UART3, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +/* + * Note that on Innovator-1510 UART2 pins conflict with USB2. + * By default UART2 does not work on Innovator-1510 if you have + * USB OHCI enabled. To use UART2, you must disable USB2 first. + */ +void __init omap_serial_init(void) +{ + int i; + + if (cpu_is_omap15xx()) { + serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; + } + + for (i = 0; i < ARRAY_SIZE(serial_platform_data) - 1; i++) { + /* Static mapping, never released */ + serial_platform_data[i].membase = + ioremap(serial_platform_data[i].mapbase, SZ_2K); + if (!serial_platform_data[i].membase) { + printk(KERN_ERR "Could not ioremap uart%i\n", i); + continue; + } + switch (i) { + case 0: + uart1_ck = clk_get(NULL, "uart1_ck"); + if (IS_ERR(uart1_ck)) + printk("Could not get uart1_ck\n"); + else { + clk_prepare_enable(uart1_ck); + if (cpu_is_omap15xx()) + clk_set_rate(uart1_ck, 12000000); + } + break; + case 1: + uart2_ck = clk_get(NULL, "uart2_ck"); + if (IS_ERR(uart2_ck)) + printk("Could not get uart2_ck\n"); + else { + clk_prepare_enable(uart2_ck); + if (cpu_is_omap15xx()) + clk_set_rate(uart2_ck, 12000000); + else + clk_set_rate(uart2_ck, 48000000); + } + break; + case 2: + uart3_ck = clk_get(NULL, "uart3_ck"); + if (IS_ERR(uart3_ck)) + printk("Could not get uart3_ck\n"); + else { + clk_prepare_enable(uart3_ck); + if (cpu_is_omap15xx()) + clk_set_rate(uart3_ck, 12000000); + } + break; + } + omap_serial_reset(&serial_platform_data[i]); + } +} + +#ifdef CONFIG_OMAP_SERIAL_WAKE + +static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id) +{ + /* Need to do something with serial port right after wake-up? */ + return IRQ_HANDLED; +} + +/* + * Reroutes serial RX lines to GPIO lines for the duration of + * sleep to allow waking up the device from serial port even + * in deep sleep. + */ +void omap_serial_wake_trigger(int enable) +{ + if (!cpu_is_omap16xx()) + return; + + if (uart1_ck != NULL) { + if (enable) + omap_cfg_reg(V14_16XX_GPIO37); + else + omap_cfg_reg(V14_16XX_UART1_RX); + } + if (uart2_ck != NULL) { + if (enable) + omap_cfg_reg(R9_16XX_GPIO18); + else + omap_cfg_reg(R9_16XX_UART2_RX); + } + if (uart3_ck != NULL) { + if (enable) + omap_cfg_reg(L14_16XX_GPIO49); + else + omap_cfg_reg(L14_16XX_UART3_RX); + } +} + +static void __init omap_serial_set_port_wakeup(int idx) +{ + struct gpio_desc *d; + int ret; + + d = gpiod_get_index(NULL, "wakeup", idx, GPIOD_IN); + if (IS_ERR(d)) { + pr_err("Unable to get UART wakeup GPIO descriptor\n"); + return; + } + ret = request_irq(gpiod_to_irq(d), &omap_serial_wake_interrupt, + IRQF_TRIGGER_RISING, "serial wakeup", NULL); + if (ret) { + gpiod_put(d); + pr_err("No interrupt for UART%d wake GPIO\n", idx + 1); + return; + } + enable_irq_wake(gpiod_to_irq(d)); +} + + +int __init omap_serial_wakeup_init(void) +{ + if (!cpu_is_omap16xx()) + return 0; + + if (uart1_ck != NULL) + omap_serial_set_port_wakeup(0); + if (uart2_ck != NULL) + omap_serial_set_port_wakeup(1); + if (uart3_ck != NULL) + omap_serial_set_port_wakeup(2); + + return 0; +} + +#endif /* CONFIG_OMAP_SERIAL_WAKE */ + +static int __init omap_init(void) +{ + if (!cpu_class_is_omap1()) + return -ENODEV; + + return platform_device_register(&serial_device); +} +arch_initcall(omap_init); -- cgit v1.3.1