From b4940f6c3e0e021a8612e8eee5d93ecba9ec9f32 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:58:30 +0200 Subject: tty: make check_tty_count() void The return value is unused, so drop it. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712085830.4908-1-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3959efc717aa..e23e416aae93 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -270,7 +270,7 @@ static int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, } /* Caller must hold tty_lock */ -static int check_tty_count(struct tty_struct *tty, const char *routine) +static void check_tty_count(struct tty_struct *tty, const char *routine) { #ifdef CHECK_TTY_COUNT struct list_head *p; @@ -290,10 +290,8 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) if (tty->count != (count + kopen_count)) { tty_warn(tty, "%s: tty->count(%d) != (#fd's(%d) + #kopen's(%d))\n", routine, tty->count, count, kopen_count); - return (count + kopen_count); } #endif - return 0; } /** -- cgit v1.2.3 From b30a3d396b4c4fccc73a4922d594bb589afb5bee Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 08:42:13 +0200 Subject: n_tty: drop fp from n_tty_receive_buf_real_raw() The 'fp' parameter of n_tty_receive_buf_real_raw() is unused, so drop it. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712064216.12150-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 552e8a741562..1599012f20c8 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1502,7 +1502,7 @@ static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const unsigned cha static void n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count) + int count) { struct n_tty_data *ldata = tty->disc_data; size_t n, head; @@ -1597,7 +1597,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, size_t la_count = min_t(size_t, ldata->lookahead_count, count); if (ldata->real_raw) - n_tty_receive_buf_real_raw(tty, cp, fp, count); + n_tty_receive_buf_real_raw(tty, cp, count); else if (ldata->raw || (L_EXTPROC(tty) && !preops)) n_tty_receive_buf_raw(tty, cp, fp, count); else if (tty->closing && !L_EXTPROC(tty)) { -- cgit v1.2.3 From f6f847ff8d6662977fd7f7199152b87ef029e704 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 08:42:14 +0200 Subject: n_tty: simplify and sanitize zero_buffer() * Make 'tty' parameter const as we only look at tty flags here. * Make 'size' parameter of size_t type as everyone passes that and memset() (the consumer) expects size_t too. So be consistent. * Remove redundant local variables, place the content directly to the 'if'. * Use 0 instead of 0x00 in memset(). The former is more obvious. No functional changes expected. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712064216.12150-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 1599012f20c8..c1859ae263eb 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -158,13 +158,10 @@ static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i) } /* If we are not echoing the data, perhaps this is a secret so erase it */ -static void zero_buffer(struct tty_struct *tty, u8 *buffer, int size) +static void zero_buffer(const struct tty_struct *tty, u8 *buffer, size_t size) { - bool icanon = !!L_ICANON(tty); - bool no_echo = !L_ECHO(tty); - - if (icanon && no_echo) - memset(buffer, 0x00, size); + if (L_ICANON(tty) && !L_ECHO(tty)) + memset(buffer, 0, size); } static void tty_copy(struct tty_struct *tty, void *to, size_t tail, size_t n) -- cgit v1.2.3 From 32042446c030b677f3bf10081876d9bd078740a2 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 08:42:15 +0200 Subject: n_tty: pass ldata to canon_skip_eof() directly 'tty' is not needed in canon_skip_eof(), so we can pass 'ldata' directly instead. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712064216.12150-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index c1859ae263eb..bab7005ef520 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2053,9 +2053,8 @@ static bool canon_copy_from_read_buf(struct tty_struct *tty, * EOF (special EOL character that's a __DISABLED_CHAR) * in the stream, silently eat the EOF. */ -static void canon_skip_eof(struct tty_struct *tty) +static void canon_skip_eof(struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; size_t tail, canon_head; canon_head = smp_load_acquire(&ldata->canon_head); @@ -2153,7 +2152,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, * releasing the lock and returning done. */ if (!nr) - canon_skip_eof(tty); + canon_skip_eof(ldata); else if (canon_copy_from_read_buf(tty, &kb, &nr)) return kb - kbuf; } else { -- cgit v1.2.3 From 5bedcf70c6be530c6c4a7f78a820dd19566996e0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 08:42:16 +0200 Subject: n_tty: make many tty parameters const In many n_tty functions, the 'tty' parameter is used to either obtain 'ldata', or test the tty flags. So mark 'tty' in them const to make obvious that it is only read. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712064216.12150-5-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index bab7005ef520..0043cc84b91a 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -164,7 +164,8 @@ static void zero_buffer(const struct tty_struct *tty, u8 *buffer, size_t size) memset(buffer, 0, size); } -static void tty_copy(struct tty_struct *tty, void *to, size_t tail, size_t n) +static void tty_copy(const struct tty_struct *tty, void *to, size_t tail, + size_t n) { struct n_tty_data *ldata = tty->disc_data; size_t size = N_TTY_BUF_SIZE - tail; @@ -195,7 +196,7 @@ static void tty_copy(struct tty_struct *tty, void *to, size_t tail, size_t n) * * n_tty_read()/consumer path: * holds non-exclusive %termios_rwsem */ -static void n_tty_kick_worker(struct tty_struct *tty) +static void n_tty_kick_worker(const struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; @@ -215,9 +216,9 @@ static void n_tty_kick_worker(struct tty_struct *tty) } } -static ssize_t chars_in_buffer(struct tty_struct *tty) +static ssize_t chars_in_buffer(const struct tty_struct *tty) { - struct n_tty_data *ldata = tty->disc_data; + const struct n_tty_data *ldata = tty->disc_data; ssize_t n = 0; if (!ldata->icanon) @@ -393,7 +394,7 @@ static inline int is_utf8_continuation(unsigned char c) * Returns: true if the utf8 character @c is a multibyte continuation character * and the terminal is in unicode mode. */ -static inline int is_continuation(unsigned char c, struct tty_struct *tty) +static inline int is_continuation(unsigned char c, const struct tty_struct *tty) { return I_IUTF8(tty) && is_utf8_continuation(c); } @@ -913,7 +914,7 @@ static void echo_char_raw(unsigned char c, struct n_tty_data *ldata) * This variant tags control characters to be echoed as "^X" (where X is the * letter representing the control char). */ -static void echo_char(unsigned char c, struct tty_struct *tty) +static void echo_char(unsigned char c, const struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; @@ -951,7 +952,7 @@ static inline void finish_erasing(struct n_tty_data *ldata) * Locking: n_tty_receive_buf()/producer path: * caller holds non-exclusive %termios_rwsem */ -static void eraser(unsigned char c, struct tty_struct *tty) +static void eraser(unsigned char c, const struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; enum { ERASE, WERASE, KILL } kill_type; @@ -1167,7 +1168,7 @@ static void n_tty_receive_break(struct tty_struct *tty) * Called from the receive_buf path so single threaded. Does not need locking * as num_overrun and overrun_time are function private. */ -static void n_tty_receive_overrun(struct tty_struct *tty) +static void n_tty_receive_overrun(const struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; @@ -1191,7 +1192,8 @@ static void n_tty_receive_overrun(struct tty_struct *tty) * Locking: n_tty_receive_buf()/producer path: * caller holds non-exclusive %termios_rwsem */ -static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c) +static void n_tty_receive_parity_error(const struct tty_struct *tty, + unsigned char c) { struct n_tty_data *ldata = tty->disc_data; @@ -1498,8 +1500,8 @@ static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const unsigned cha } static void -n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp, - int count) +n_tty_receive_buf_real_raw(const struct tty_struct *tty, + const unsigned char *cp, int count) { struct n_tty_data *ldata = tty->disc_data; size_t n, head; @@ -1900,9 +1902,9 @@ static int n_tty_open(struct tty_struct *tty) return 0; } -static inline int input_available_p(struct tty_struct *tty, int poll) +static inline int input_available_p(const struct tty_struct *tty, int poll) { - struct n_tty_data *ldata = tty->disc_data; + const struct n_tty_data *ldata = tty->disc_data; int amt = poll && !TIME_CHAR(tty) && MIN_CHAR(tty) ? MIN_CHAR(tty) : 1; if (ldata->icanon && !L_EXTPROC(tty)) @@ -1929,7 +1931,7 @@ static inline int input_available_p(struct tty_struct *tty, int poll) * caller holds non-exclusive %termios_rwsem; * read_tail published */ -static bool copy_from_read_buf(struct tty_struct *tty, +static bool copy_from_read_buf(const struct tty_struct *tty, unsigned char **kbp, size_t *nr) @@ -1984,7 +1986,7 @@ static bool copy_from_read_buf(struct tty_struct *tty, * caller holds non-exclusive %termios_rwsem; * read_tail published */ -static bool canon_copy_from_read_buf(struct tty_struct *tty, +static bool canon_copy_from_read_buf(const struct tty_struct *tty, unsigned char **kbp, size_t *nr) { -- cgit v1.2.3 From 00ef7eff2f2fcb28a3a4b5697ab6ce242e041091 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:02 +0200 Subject: tty: sysrq: rename and re-type i in sysrq_handle_loglevel() 'i' is a too generic name for something which carries a 'loglevel'. Name it as such and make it 'u8', the same as key will become in the next patches. Note that we are not stripping any high bits away, 'key' is given only 8bit values. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712081811.29004-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/sysrq.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index b6e70c5cfa17..262d0970ccb5 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -100,12 +100,11 @@ __setup("sysrq_always_enabled", sysrq_always_enabled_setup); static void sysrq_handle_loglevel(int key) { - int i; + u8 loglevel = key - '0'; - i = key - '0'; console_loglevel = CONSOLE_LOGLEVEL_DEFAULT; - pr_info("Loglevel set to %d\n", i); - console_loglevel = i; + pr_info("Loglevel set to %u\n", loglevel); + console_loglevel = loglevel; } static const struct sysrq_key_op sysrq_loglevel_op = { .handler = sysrq_handle_loglevel, -- cgit v1.2.3 From bcb48185eddf72d5e2a9f745aaec030778e3ea35 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:03 +0200 Subject: tty: sysrq: switch sysrq handlers from int to u8 The passed parameter to sysrq handlers is a key (a character). So change the type from 'int' to 'u8'. Let it specifically be 'u8' for two reasons: * unsigned: unsigned values come from the upper layers (devices) and the tty layer assumes unsigned on most places, and * 8-bit: as that what's supposed to be one day in all the layers built on the top of tty. (Currently, we use mostly 'unsigned char' and somewhere still only 'char'. (But that also translates to the former thanks to -funsigned-char.)) Signed-off-by: Jiri Slaby (SUSE) Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner Cc: Huacai Chen Cc: WANG Xuerui Cc: Thomas Bogendoerfer Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: "David S. Miller" Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Cc: Jason Wessel Cc: Daniel Thompson Cc: Douglas Anderson Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: Pavel Machek Cc: "Paul E. McKenney" Cc: Frederic Weisbecker Cc: Neeraj Upadhyay Cc: Joel Fernandes Cc: Josh Triplett Cc: Boqun Feng Cc: Steven Rostedt Cc: Mathieu Desnoyers Cc: Lai Jiangshan Cc: Zqiang Acked-by: Thomas Zimmermann # DRM Acked-by: WANG Xuerui # loongarch Acked-by: Paul E. McKenney Acked-by: Daniel Thompson Link: https://lore.kernel.org/r/20230712081811.29004-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/setup.c | 2 +- arch/loongarch/kernel/sysrq.c | 2 +- arch/mips/kernel/sysrq.c | 2 +- arch/powerpc/xmon/xmon.c | 2 +- arch/sparc/kernel/process_64.c | 4 ++-- drivers/gpu/drm/drm_fb_helper.c | 2 +- drivers/tty/sysrq.c | 40 ++++++++++++++++++++-------------------- include/linux/sysrq.h | 2 +- kernel/debug/debug_core.c | 2 +- kernel/power/poweroff.c | 2 +- kernel/rcu/tree_stall.h | 2 +- 11 files changed, 31 insertions(+), 31 deletions(-) diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index b650ff1cb022..91fb3714ebc2 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -422,7 +422,7 @@ register_cpus(void) arch_initcall(register_cpus); #ifdef CONFIG_MAGIC_SYSRQ -static void sysrq_reboot_handler(int unused) +static void sysrq_reboot_handler(u8 unused) { machine_halt(); } diff --git a/arch/loongarch/kernel/sysrq.c b/arch/loongarch/kernel/sysrq.c index 366baef72d29..e663c10fa39c 100644 --- a/arch/loongarch/kernel/sysrq.c +++ b/arch/loongarch/kernel/sysrq.c @@ -43,7 +43,7 @@ static void sysrq_tlbdump_othercpus(struct work_struct *dummy) static DECLARE_WORK(sysrq_tlbdump, sysrq_tlbdump_othercpus); #endif -static void sysrq_handle_tlbdump(int key) +static void sysrq_handle_tlbdump(u8 key) { sysrq_tlbdump_single(NULL); #ifdef CONFIG_SMP diff --git a/arch/mips/kernel/sysrq.c b/arch/mips/kernel/sysrq.c index 9c1a2019113b..2e98049fe783 100644 --- a/arch/mips/kernel/sysrq.c +++ b/arch/mips/kernel/sysrq.c @@ -44,7 +44,7 @@ static void sysrq_tlbdump_othercpus(struct work_struct *dummy) static DECLARE_WORK(sysrq_tlbdump, sysrq_tlbdump_othercpus); #endif -static void sysrq_handle_tlbdump(int key) +static void sysrq_handle_tlbdump(u8 key) { sysrq_tlbdump_single(NULL); #ifdef CONFIG_SMP diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index fae747cc57d2..196eeba0a70b 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -3991,7 +3991,7 @@ static void xmon_init(int enable) } #ifdef CONFIG_MAGIC_SYSRQ -static void sysrq_handle_xmon(int key) +static void sysrq_handle_xmon(u8 key) { if (xmon_is_locked_down()) { clear_all_bpt(); diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index b51d8fb0ecdc..4dee88af403f 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -295,7 +295,7 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) #ifdef CONFIG_MAGIC_SYSRQ -static void sysrq_handle_globreg(int key) +static void sysrq_handle_globreg(u8 key) { trigger_all_cpu_backtrace(); } @@ -370,7 +370,7 @@ static void pmu_snapshot_all_cpus(void) spin_unlock_irqrestore(&global_cpu_snapshot_lock, flags); } -static void sysrq_handle_globpmu(int key) +static void sysrq_handle_globpmu(u8 key) { pmu_snapshot_all_cpus(); } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 61a5d450cc20..d612133e2cf7 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -301,7 +301,7 @@ static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); -static void drm_fb_helper_sysrq(int dummy1) +static void drm_fb_helper_sysrq(u8 dummy1) { schedule_work(&drm_fb_helper_restore_work); } diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 262d0970ccb5..2d3a7836f835 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -98,7 +98,7 @@ static int __init sysrq_always_enabled_setup(char *str) __setup("sysrq_always_enabled", sysrq_always_enabled_setup); -static void sysrq_handle_loglevel(int key) +static void sysrq_handle_loglevel(u8 key) { u8 loglevel = key - '0'; @@ -114,7 +114,7 @@ static const struct sysrq_key_op sysrq_loglevel_op = { }; #ifdef CONFIG_VT -static void sysrq_handle_SAK(int key) +static void sysrq_handle_SAK(u8 key) { struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; @@ -131,7 +131,7 @@ static const struct sysrq_key_op sysrq_SAK_op = { #endif #ifdef CONFIG_VT -static void sysrq_handle_unraw(int key) +static void sysrq_handle_unraw(u8 key) { vt_reset_unicode(fg_console); } @@ -146,7 +146,7 @@ static const struct sysrq_key_op sysrq_unraw_op = { #define sysrq_unraw_op (*(const struct sysrq_key_op *)NULL) #endif /* CONFIG_VT */ -static void sysrq_handle_crash(int key) +static void sysrq_handle_crash(u8 key) { /* release the RCU read lock before crashing */ rcu_read_unlock(); @@ -160,7 +160,7 @@ static const struct sysrq_key_op sysrq_crash_op = { .enable_mask = SYSRQ_ENABLE_DUMP, }; -static void sysrq_handle_reboot(int key) +static void sysrq_handle_reboot(u8 key) { lockdep_off(); local_irq_enable(); @@ -175,7 +175,7 @@ static const struct sysrq_key_op sysrq_reboot_op = { const struct sysrq_key_op *__sysrq_reboot_op = &sysrq_reboot_op; -static void sysrq_handle_sync(int key) +static void sysrq_handle_sync(u8 key) { emergency_sync(); } @@ -186,7 +186,7 @@ static const struct sysrq_key_op sysrq_sync_op = { .enable_mask = SYSRQ_ENABLE_SYNC, }; -static void sysrq_handle_show_timers(int key) +static void sysrq_handle_show_timers(u8 key) { sysrq_timer_list_show(); } @@ -197,7 +197,7 @@ static const struct sysrq_key_op sysrq_show_timers_op = { .action_msg = "Show clockevent devices & pending hrtimers (no others)", }; -static void sysrq_handle_mountro(int key) +static void sysrq_handle_mountro(u8 key) { emergency_remount(); } @@ -209,7 +209,7 @@ static const struct sysrq_key_op sysrq_mountro_op = { }; #ifdef CONFIG_LOCKDEP -static void sysrq_handle_showlocks(int key) +static void sysrq_handle_showlocks(u8 key) { debug_show_all_locks(); } @@ -249,7 +249,7 @@ static void sysrq_showregs_othercpus(struct work_struct *dummy) static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); -static void sysrq_handle_showallcpus(int key) +static void sysrq_handle_showallcpus(u8 key) { /* * Fall back to the workqueue based printing if the @@ -282,7 +282,7 @@ static const struct sysrq_key_op sysrq_showallcpus_op = { #define sysrq_showallcpus_op (*(const struct sysrq_key_op *)NULL) #endif -static void sysrq_handle_showregs(int key) +static void sysrq_handle_showregs(u8 key) { struct pt_regs *regs = NULL; @@ -299,7 +299,7 @@ static const struct sysrq_key_op sysrq_showregs_op = { .enable_mask = SYSRQ_ENABLE_DUMP, }; -static void sysrq_handle_showstate(int key) +static void sysrq_handle_showstate(u8 key) { show_state(); show_all_workqueues(); @@ -311,7 +311,7 @@ static const struct sysrq_key_op sysrq_showstate_op = { .enable_mask = SYSRQ_ENABLE_DUMP, }; -static void sysrq_handle_showstate_blocked(int key) +static void sysrq_handle_showstate_blocked(u8 key) { show_state_filter(TASK_UNINTERRUPTIBLE); } @@ -325,7 +325,7 @@ static const struct sysrq_key_op sysrq_showstate_blocked_op = { #ifdef CONFIG_TRACING #include -static void sysrq_ftrace_dump(int key) +static void sysrq_ftrace_dump(u8 key) { ftrace_dump(DUMP_ALL); } @@ -339,7 +339,7 @@ static const struct sysrq_key_op sysrq_ftrace_dump_op = { #define sysrq_ftrace_dump_op (*(const struct sysrq_key_op *)NULL) #endif -static void sysrq_handle_showmem(int key) +static void sysrq_handle_showmem(u8 key) { show_mem(0, NULL); } @@ -369,7 +369,7 @@ static void send_sig_all(int sig) read_unlock(&tasklist_lock); } -static void sysrq_handle_term(int key) +static void sysrq_handle_term(u8 key) { send_sig_all(SIGTERM); console_loglevel = CONSOLE_LOGLEVEL_DEBUG; @@ -400,7 +400,7 @@ static void moom_callback(struct work_struct *ignored) static DECLARE_WORK(moom_work, moom_callback); -static void sysrq_handle_moom(int key) +static void sysrq_handle_moom(u8 key) { schedule_work(&moom_work); } @@ -412,7 +412,7 @@ static const struct sysrq_key_op sysrq_moom_op = { }; #ifdef CONFIG_BLOCK -static void sysrq_handle_thaw(int key) +static void sysrq_handle_thaw(u8 key) { emergency_thaw_all(); } @@ -426,7 +426,7 @@ static const struct sysrq_key_op sysrq_thaw_op = { #define sysrq_thaw_op (*(const struct sysrq_key_op *)NULL) #endif -static void sysrq_handle_kill(int key) +static void sysrq_handle_kill(u8 key) { send_sig_all(SIGKILL); console_loglevel = CONSOLE_LOGLEVEL_DEBUG; @@ -438,7 +438,7 @@ static const struct sysrq_key_op sysrq_kill_op = { .enable_mask = SYSRQ_ENABLE_SIGNAL, }; -static void sysrq_handle_unrt(int key) +static void sysrq_handle_unrt(u8 key) { normalize_rt_tasks(); } diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index 3a582ec7a2f1..bb8d07814b0e 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h @@ -30,7 +30,7 @@ #define SYSRQ_ENABLE_RTNICE 0x0100 struct sysrq_key_op { - void (* const handler)(int); + void (* const handler)(u8); const char * const help_msg; const char * const action_msg; const int enable_mask; diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index d5e9ccde3ab8..621037a0aa87 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -968,7 +968,7 @@ static int __init opt_kgdb_con(char *str) early_param("kgdbcon", opt_kgdb_con); #ifdef CONFIG_MAGIC_SYSRQ -static void sysrq_handle_dbg(int key) +static void sysrq_handle_dbg(u8 key) { if (!dbg_io_ops) { pr_crit("ERROR: No KGDB I/O module available\n"); diff --git a/kernel/power/poweroff.c b/kernel/power/poweroff.c index 562aa0e450ed..1f306f158696 100644 --- a/kernel/power/poweroff.c +++ b/kernel/power/poweroff.c @@ -23,7 +23,7 @@ static void do_poweroff(struct work_struct *dummy) static DECLARE_WORK(poweroff_work, do_poweroff); -static void handle_poweroff(int key) +static void handle_poweroff(u8 key) { /* run sysrq poweroff on boot cpu */ schedule_work_on(cpumask_first(cpu_online_mask), &poweroff_work); diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h index b10b8349bb2a..6f06dc12904a 100644 --- a/kernel/rcu/tree_stall.h +++ b/kernel/rcu/tree_stall.h @@ -1035,7 +1035,7 @@ static bool sysrq_rcu; module_param(sysrq_rcu, bool, 0444); /* Dump grace-period-request information due to commandeered sysrq. */ -static void sysrq_show_rcu(int key) +static void sysrq_show_rcu(u8 key) { show_rcu_gp_kthreads(); } -- cgit v1.2.3 From 8ac20a03da56d56a54b01dd0b62254826a84474d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:04 +0200 Subject: tty: sysrq: switch the rest of keys to u8 Propagate u8 more from the bottom to the interface, so that sysrq callers (usually drivers) see that u8 is expected. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712081811.29004-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/sysrq.c | 16 ++++++++-------- include/linux/sysrq.h | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 2d3a7836f835..0a556628a255 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -530,7 +530,7 @@ static const struct sysrq_key_op *sysrq_key_table[62] = { }; /* key2index calculation, -1 on invalid index */ -static int sysrq_key_table_key2index(int key) +static int sysrq_key_table_key2index(u8 key) { int retval; @@ -548,7 +548,7 @@ static int sysrq_key_table_key2index(int key) /* * get and put functions for the table, exposed to modules. */ -static const struct sysrq_key_op *__sysrq_get_key_op(int key) +static const struct sysrq_key_op *__sysrq_get_key_op(u8 key) { const struct sysrq_key_op *op_p = NULL; int i; @@ -560,7 +560,7 @@ static const struct sysrq_key_op *__sysrq_get_key_op(int key) return op_p; } -static void __sysrq_put_key_op(int key, const struct sysrq_key_op *op_p) +static void __sysrq_put_key_op(u8 key, const struct sysrq_key_op *op_p) { int i = sysrq_key_table_key2index(key); @@ -568,7 +568,7 @@ static void __sysrq_put_key_op(int key, const struct sysrq_key_op *op_p) sysrq_key_table[i] = op_p; } -void __handle_sysrq(int key, bool check_mask) +void __handle_sysrq(u8 key, bool check_mask) { const struct sysrq_key_op *op_p; int orig_log_level; @@ -627,7 +627,7 @@ void __handle_sysrq(int key, bool check_mask) suppress_printk = orig_suppress_printk; } -void handle_sysrq(int key) +void handle_sysrq(u8 key) { if (sysrq_on()) __handle_sysrq(key, true); @@ -1111,7 +1111,7 @@ int sysrq_toggle_support(int enable_mask) } EXPORT_SYMBOL_GPL(sysrq_toggle_support); -static int __sysrq_swap_key_ops(int key, const struct sysrq_key_op *insert_op_p, +static int __sysrq_swap_key_ops(u8 key, const struct sysrq_key_op *insert_op_p, const struct sysrq_key_op *remove_op_p) { int retval; @@ -1135,13 +1135,13 @@ static int __sysrq_swap_key_ops(int key, const struct sysrq_key_op *insert_op_p, return retval; } -int register_sysrq_key(int key, const struct sysrq_key_op *op_p) +int register_sysrq_key(u8 key, const struct sysrq_key_op *op_p) { return __sysrq_swap_key_ops(key, op_p, NULL); } EXPORT_SYMBOL(register_sysrq_key); -int unregister_sysrq_key(int key, const struct sysrq_key_op *op_p) +int unregister_sysrq_key(u8 key, const struct sysrq_key_op *op_p) { return __sysrq_swap_key_ops(key, NULL, op_p); } diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index bb8d07814b0e..bdca467ebb77 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h @@ -43,10 +43,10 @@ struct sysrq_key_op { * are available -- else NULL's). */ -void handle_sysrq(int key); -void __handle_sysrq(int key, bool check_mask); -int register_sysrq_key(int key, const struct sysrq_key_op *op); -int unregister_sysrq_key(int key, const struct sysrq_key_op *op); +void handle_sysrq(u8 key); +void __handle_sysrq(u8 key, bool check_mask); +int register_sysrq_key(u8 key, const struct sysrq_key_op *op); +int unregister_sysrq_key(u8 key, const struct sysrq_key_op *op); extern const struct sysrq_key_op *__sysrq_reboot_op; int sysrq_toggle_support(int enable_mask); @@ -54,20 +54,20 @@ int sysrq_mask(void); #else -static inline void handle_sysrq(int key) +static inline void handle_sysrq(u8 key) { } -static inline void __handle_sysrq(int key, bool check_mask) +static inline void __handle_sysrq(u8 key, bool check_mask) { } -static inline int register_sysrq_key(int key, const struct sysrq_key_op *op) +static inline int register_sysrq_key(u8 key, const struct sysrq_key_op *op) { return -EINVAL; } -static inline int unregister_sysrq_key(int key, const struct sysrq_key_op *op) +static inline int unregister_sysrq_key(u8 key, const struct sysrq_key_op *op) { return -EINVAL; } -- cgit v1.2.3 From a27f3b72337dd6884a5c8761574503cfdd9cf37e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:05 +0200 Subject: tty: sysrq: use switch in sysrq_key_table_key2index() Using switch with range cases makes the code more aligned and readable. Expand also that 36 as explicit addition of 10 + 26 to make the source of the constant more obvious. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712081811.29004-5-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/sysrq.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 0a556628a255..28127bcb146d 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -532,17 +532,16 @@ static const struct sysrq_key_op *sysrq_key_table[62] = { /* key2index calculation, -1 on invalid index */ static int sysrq_key_table_key2index(u8 key) { - int retval; - - if ((key >= '0') && (key <= '9')) - retval = key - '0'; - else if ((key >= 'a') && (key <= 'z')) - retval = key + 10 - 'a'; - else if ((key >= 'A') && (key <= 'Z')) - retval = key + 36 - 'A'; - else - retval = -1; - return retval; + switch (key) { + case '0' ... '9': + return key - '0'; + case 'a' ... 'z': + return key - 'a' + 10; + case 'A' ... 'Z': + return key - 'A' + 10 + 26; + default: + return -1; + } } /* -- cgit v1.2.3 From 12ae2359eb2f1b880863b266a2e72f65f043eacd Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:06 +0200 Subject: serial: convert uart sysrq handling to u8 Propagate u8 from the sysrq code further up to serial's uart_handle_sysrq_char() and friends. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712081811.29004-6-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 4 ++-- include/linux/serial_core.h | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 831d033611e6..7e37db9adbd4 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3505,7 +3505,7 @@ void uart_insert_char(struct uart_port *port, unsigned int status, EXPORT_SYMBOL_GPL(uart_insert_char); #ifdef CONFIG_MAGIC_SYSRQ_SERIAL -static const char sysrq_toggle_seq[] = CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE; +static const u8 sysrq_toggle_seq[] = CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE; static void uart_sysrq_on(struct work_struct *w) { @@ -3528,7 +3528,7 @@ static DECLARE_WORK(sysrq_enable_work, uart_sysrq_on); * Returns: %false if @ch is out of enabling sequence and should be * handled some other way, %true if @ch was consumed. */ -bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch) +bool uart_try_toggle_sysrq(struct uart_port *port, u8 ch) { int sysrq_toggle_seq_len = strlen(sysrq_toggle_seq); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 6d58c57acdaa..14dd85ee849e 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -569,7 +569,7 @@ struct uart_port { struct serial_port_device *port_dev; /* serial core port device */ unsigned long sysrq; /* sysrq timeout */ - unsigned int sysrq_ch; /* char for sysrq */ + u8 sysrq_ch; /* char for sysrq */ unsigned char has_sysrq; unsigned char sysrq_seq; /* index in sysrq_toggle_seq */ @@ -910,9 +910,9 @@ void uart_xchar_out(struct uart_port *uport, int offset); #ifdef CONFIG_MAGIC_SYSRQ_SERIAL #define SYSRQ_TIMEOUT (HZ * 5) -bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch); +bool uart_try_toggle_sysrq(struct uart_port *port, u8 ch); -static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) +static inline int uart_handle_sysrq_char(struct uart_port *port, u8 ch) { if (!port->sysrq) return 0; @@ -931,7 +931,7 @@ static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch return 0; } -static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) +static inline int uart_prepare_sysrq_char(struct uart_port *port, u8 ch) { if (!port->sysrq) return 0; @@ -952,7 +952,7 @@ static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int c static inline void uart_unlock_and_check_sysrq(struct uart_port *port) { - int sysrq_ch; + u8 sysrq_ch; if (!port->has_sysrq) { spin_unlock(&port->lock); @@ -971,7 +971,7 @@ static inline void uart_unlock_and_check_sysrq(struct uart_port *port) static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port, unsigned long flags) { - int sysrq_ch; + u8 sysrq_ch; if (!port->has_sysrq) { spin_unlock_irqrestore(&port->lock, flags); @@ -987,11 +987,11 @@ static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port handle_sysrq(sysrq_ch); } #else /* CONFIG_MAGIC_SYSRQ_SERIAL */ -static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) +static inline int uart_handle_sysrq_char(struct uart_port *port, u8 ch) { return 0; } -static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) +static inline int uart_prepare_sysrq_char(struct uart_port *port, u8 ch) { return 0; } -- cgit v1.2.3 From df007fa02560435f7ffbc62147cc0084f8241899 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:07 +0200 Subject: serial: make uart_insert_char() accept u8s Both the character and flag are 8-bit values. So switch from unsigned ints to u8s. The drivers will be cleaned up in the next round. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712081811.29004-7-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 2 +- include/linux/serial_core.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 7e37db9adbd4..bef507cb804c 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3486,7 +3486,7 @@ EXPORT_SYMBOL_GPL(uart_handle_cts_change); * @flag: flag for the character (see TTY_NORMAL and friends) */ void uart_insert_char(struct uart_port *port, unsigned int status, - unsigned int overrun, unsigned int ch, unsigned int flag) + unsigned int overrun, u8 ch, u8 flag) { struct tty_port *tport = &port->state->port; diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 14dd85ee849e..105d2cdc0126 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -903,7 +903,7 @@ void uart_handle_dcd_change(struct uart_port *uport, bool active); void uart_handle_cts_change(struct uart_port *uport, bool active); void uart_insert_char(struct uart_port *port, unsigned int status, - unsigned int overrun, unsigned int ch, unsigned int flag); + unsigned int overrun, u8 ch, u8 flag); void uart_xchar_out(struct uart_port *uport, int offset); -- cgit v1.2.3 From 1225541cfd5f0b32edfd680ab6b3af5ad4af36c4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:08 +0200 Subject: serial: pass state to __uart_start() directly __uart_start() does not need a tty struct. It works only with uart_state. So pass the latter directly. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712081811.29004-8-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index bef507cb804c..306ea1a560e6 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -133,9 +133,8 @@ static void uart_stop(struct tty_struct *tty) uart_port_unlock(port, flags); } -static void __uart_start(struct tty_struct *tty) +static void __uart_start(struct uart_state *state) { - struct uart_state *state = tty->driver_data; struct uart_port *port = state->uart_port; struct serial_port_device *port_dev; int err; @@ -170,7 +169,7 @@ static void uart_start(struct tty_struct *tty) unsigned long flags; port = uart_port_lock(state, flags); - __uart_start(tty); + __uart_start(state); uart_port_unlock(port, flags); } @@ -239,7 +238,7 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state if (!old_hw_stopped) uport->ops->stop_tx(uport); else - __uart_start(tty); + __uart_start(state); } spin_unlock_irq(&uport->lock); } @@ -619,7 +618,7 @@ static int uart_write(struct tty_struct *tty, ret += c; } - __uart_start(tty); + __uart_start(state); uart_port_unlock(port, flags); return ret; } -- cgit v1.2.3 From 29ec63ef16fce338774b9ba306ea530190bf772a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:09 +0200 Subject: serial: arc_uart: simplify flags handling in arc_serial_rx_chars() * move the declaration of flg (with the initializer) to the loop, so there is no need to reset it to TTY_NORMAL by an 'else' branch. * use TTY_NORMAL as initializer above, not a magic zero constant * remove the outer 'if' from this construct: if (S & (A | B)) { if (S & A) X; if (S & B) Y; } * drop unlikely() as I doubt it has any benefits here. If it does, provide numbers. All four make the code easier to read. Signed-off-by: Jiri Slaby (SUSE) Cc: Vineet Gupta Acked-by: Vineet Gupta Link: https://lore.kernel.org/r/20230712081811.29004-9-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/arc_uart.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 4b2512eef577..835903488acb 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -195,8 +195,6 @@ static void arc_serial_start_tx(struct uart_port *port) static void arc_serial_rx_chars(struct uart_port *port, unsigned int status) { - unsigned int ch, flg = 0; - /* * UART has 4 deep RX-FIFO. Driver's recongnition of this fact * is very subtle. Here's how ... @@ -207,24 +205,23 @@ static void arc_serial_rx_chars(struct uart_port *port, unsigned int status) * controller, which is indeed the Rx-FIFO. */ do { + unsigned int ch, flg = TTY_NORMAL; + /* * This could be an Rx Intr for err (no data), * so check err and clear that Intr first */ - if (unlikely(status & (RXOERR | RXFERR))) { - if (status & RXOERR) { - port->icount.overrun++; - flg = TTY_OVERRUN; - UART_CLR_STATUS(port, RXOERR); - } - - if (status & RXFERR) { - port->icount.frame++; - flg = TTY_FRAME; - UART_CLR_STATUS(port, RXFERR); - } - } else - flg = TTY_NORMAL; + if (status & RXOERR) { + port->icount.overrun++; + flg = TTY_OVERRUN; + UART_CLR_STATUS(port, RXOERR); + } + + if (status & RXFERR) { + port->icount.frame++; + flg = TTY_FRAME; + UART_CLR_STATUS(port, RXFERR); + } if (status & RXEMPTY) continue; -- cgit v1.2.3 From 4d1fceb1b2579a450c10c7bbfbdb03e60a87eb68 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:10 +0200 Subject: serial: omap-serial: remove flag from serial_omap_rdi() The local 'flag' variable carries only TTY_NORMAL. So use that constant directly and drop the variable. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230712081811.29004-10-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 82d35dbbfa6c..16ab7ea07fa3 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -499,7 +499,6 @@ static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr) static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) { unsigned char ch = 0; - unsigned int flag; if (!(lsr & UART_LSR_DR)) return; @@ -512,13 +511,12 @@ static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) return; } - flag = TTY_NORMAL; up->port.icount.rx++; if (uart_handle_sysrq_char(&up->port, ch)) return; - uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); + uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, TTY_NORMAL); } /** -- cgit v1.2.3 From fd2b55f86b8b25afc5b6e7dff53dddb3fd0dd211 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 12 Jul 2023 10:18:11 +0200 Subject: serial: drivers: switch ch and flag to u8 Now that the serial layer explicitly expects 'u8' for flags and characters, propagate this type to drivers' (RX) routines. Note that amba-pl011's, clps711x's and st-asc's 'ch' are left unchanged because 'ch' contains not only a character, but whole status. Signed-off-by: Jiri Slaby (SUSE) Cc: Tobias Klauser Cc: Russell King Cc: Vineet Gupta Cc: Richard Genoud Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Claudiu Beznea Cc: Alexander Shiyan Cc: Baruch Siach Cc: "Maciej W. Rozycki" Cc: Taichi Sugaya Cc: Takao Orito Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: Kevin Cernekee Cc: Krzysztof Kozlowski Cc: Alim Akhtar Cc: Laxman Dewangan Cc: Thierry Reding Cc: Jonathan Hunter Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Orson Zhai Cc: Baolin Wang Cc: Chunyan Zhang Cc: Patrice Chotard Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: Hammer Hsieh Acked-by: Richard GENOUD Acked-by: Tobias Klauser Acked-by: Thierry Reding Acked-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/20230712081811.29004-11-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/21285.c | 3 ++- drivers/tty/serial/8250/8250_port.c | 3 +-- drivers/tty/serial/altera_jtaguart.c | 2 +- drivers/tty/serial/altera_uart.c | 2 +- drivers/tty/serial/amba-pl010.c | 3 ++- drivers/tty/serial/amba-pl011.c | 3 ++- drivers/tty/serial/apbuart.c | 3 ++- drivers/tty/serial/arc_uart.c | 2 +- drivers/tty/serial/atmel_serial.c | 2 +- drivers/tty/serial/clps711x.c | 3 ++- drivers/tty/serial/digicolor-usart.c | 3 +-- drivers/tty/serial/dz.c | 2 +- drivers/tty/serial/ip22zilog.c | 2 +- drivers/tty/serial/max3100.c | 3 ++- drivers/tty/serial/max310x.c | 3 ++- drivers/tty/serial/mcf.c | 2 +- drivers/tty/serial/milbeaut_usio.c | 3 +-- drivers/tty/serial/mxs-auart.c | 3 +-- drivers/tty/serial/omap-serial.c | 4 ++-- drivers/tty/serial/pxa.c | 2 +- drivers/tty/serial/rp2.c | 4 ++-- drivers/tty/serial/sa1100.c | 3 ++- drivers/tty/serial/samsung_tty.c | 3 ++- drivers/tty/serial/sb1250-duart.c | 3 ++- drivers/tty/serial/sc16is7xx.c | 3 ++- drivers/tty/serial/sccnxp.c | 3 +-- drivers/tty/serial/serial-tegra.c | 7 +++---- drivers/tty/serial/serial_txx9.c | 3 +-- drivers/tty/serial/sifive.c | 2 +- drivers/tty/serial/sprd_serial.c | 5 +++-- drivers/tty/serial/st-asc.c | 2 +- drivers/tty/serial/stm32-usart.c | 5 ++--- drivers/tty/serial/sunplus-uart.c | 2 +- drivers/tty/serial/zs.c | 3 ++- 34 files changed, 53 insertions(+), 48 deletions(-) diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index 185462fd959c..d756fcc884cb 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -117,7 +117,8 @@ static void serial21285_stop_rx(struct uart_port *port) static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) { struct uart_port *port = dev_id; - unsigned int status, ch, flag, rxs, max_count = 256; + unsigned int status, rxs, max_count = 256; + u8 ch, flag; status = *CSR_UARTFLG; while (!(status & 0x10) && max_count--) { diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 16aeb1420137..0533e75adca9 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1706,8 +1706,7 @@ static void serial8250_enable_ms(struct uart_port *port) void serial8250_read_char(struct uart_8250_port *up, u16 lsr) { struct uart_port *port = &up->port; - unsigned char ch; - char flag = TTY_NORMAL; + u8 ch, flag = TTY_NORMAL; if (likely(lsr & UART_LSR_DR)) ch = serial_in(up, UART_RX); diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 9f843d1cee40..6203ca1de769 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -110,8 +110,8 @@ static void altera_jtaguart_set_termios(struct uart_port *port, static void altera_jtaguart_rx_chars(struct uart_port *port) { - unsigned char ch; unsigned long status; + u8 ch; while ((status = readl(port->membase + ALTERA_JTAGUART_DATA_REG)) & ALTERA_JTAGUART_DATA_RVALID_MSK) { diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 9ce3d24af536..a9c41942190c 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -201,8 +201,8 @@ static void altera_uart_set_termios(struct uart_port *port, static void altera_uart_rx_chars(struct uart_port *port) { - unsigned char ch, flag; unsigned short status; + u8 ch, flag; while ((status = altera_uart_readl(port, ALTERA_UART_STATUS_REG)) & ALTERA_UART_STATUS_RRDY_MSK) { diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index a98fae2ca422..b5a7404cbacb 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -112,7 +112,8 @@ static void pl010_enable_ms(struct uart_port *port) static void pl010_rx_chars(struct uart_port *port) { - unsigned int status, ch, flag, rsr, max_count = 256; + unsigned int status, rsr, max_count = 256; + u8 ch, flag; status = readb(port->membase + UART01x_FR); while (UART_RX_DATA(status) && max_count--) { diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index c5c3f4674459..8bddc7470bcc 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -307,9 +307,10 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap, */ static int pl011_fifo_to_tty(struct uart_amba_port *uap) { - unsigned int ch, flag, fifotaken; + unsigned int ch, fifotaken; int sysrq; u16 status; + u8 flag; for (fifotaken = 0; fifotaken != 256; fifotaken++) { status = pl011_read(uap, REG_FR); diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 915ee4b0d594..372db052573d 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -70,8 +70,9 @@ static void apbuart_stop_rx(struct uart_port *port) static void apbuart_rx_chars(struct uart_port *port) { - unsigned int status, ch, rsr, flag; + unsigned int status, rsr; unsigned int max_chars = port->fifosize; + u8 ch, flag; status = UART_GET_STATUS(port); diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 835903488acb..ad4ae19b6ce3 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -205,7 +205,7 @@ static void arc_serial_rx_chars(struct uart_port *port, unsigned int status) * controller, which is indeed the Rx-FIFO. */ do { - unsigned int ch, flg = TTY_NORMAL; + u8 ch, flg = TTY_NORMAL; /* * This could be an Rx Intr for err (no data), diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 3467a875641a..ec54436969dc 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1516,8 +1516,8 @@ static void atmel_rx_from_ring(struct uart_port *port) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); struct circ_buf *ring = &atmel_port->rx_ring; - unsigned int flg; unsigned int status; + u8 flg; while (ring->head != ring->tail) { struct atmel_uart_char c; diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index e49bc4019b50..be8b8788d2e2 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -92,8 +92,9 @@ static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) { struct uart_port *port = dev_id; struct clps711x_port *s = dev_get_drvdata(port->dev); - unsigned int status, flg; + unsigned int status; u16 ch; + u8 flg; for (;;) { u32 sysflg = 0; diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c index ed197705f7ee..128b5479e813 100644 --- a/drivers/tty/serial/digicolor-usart.c +++ b/drivers/tty/serial/digicolor-usart.c @@ -136,8 +136,7 @@ static void digicolor_uart_rx(struct uart_port *port) spin_lock_irqsave(&port->lock, flags); while (1) { - u8 status, ch; - unsigned int ch_flag; + u8 status, ch, ch_flag; if (digicolor_uart_rx_empty(port)) break; diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 6b7ed7f2f3ca..667f52e83277 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c @@ -181,8 +181,8 @@ static inline void dz_receive_chars(struct dz_mux *mux) struct dz_port *dport = &mux->dport[0]; struct uart_icount *icount; int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; - unsigned char ch, flag; u16 status; + u8 ch, flag; int i; while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index b1f27e168135..845ff706bc59 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -248,8 +248,8 @@ static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up, static bool ip22zilog_receive_chars(struct uart_ip22zilog_port *up, struct zilog_channel *channel) { - unsigned char ch, flag; unsigned int r1; + u8 ch, flag; bool push = up->port.state != NULL; for (;;) { diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 86dcbff8faa3..5efb2b593be3 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -215,8 +215,9 @@ static int max3100_sr(struct max3100_port *s, u16 tx, u16 *rx) static int max3100_handlerx(struct max3100_port *s, u16 rx) { - unsigned int ch, flg, status = 0; + unsigned int status = 0; int ret = 0, cts; + u8 ch, flg; if (rx & MAX3100_R && s->rx_enabled) { dev_dbg(&s->spi->dev, "%s\n", __func__); diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 997e39449766..416d553b73a7 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -669,7 +669,8 @@ static void max310x_batch_read(struct uart_port *port, u8 *rxbuf, unsigned int l static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen) { struct max310x_one *one = to_max310x_port(port); - unsigned int sts, ch, flag, i; + unsigned int sts, i; + u8 ch, flag; if (port->read_status_mask == MAX310X_LSR_RXOVR_BIT) { /* We are just reading, happily ignoring any error conditions. diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index 3239babe12a4..1666ce012e5e 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -281,7 +281,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, static void mcf_rx_chars(struct mcf_uart *pp) { struct uart_port *port = &pp->port; - unsigned char status, ch, flag; + u8 status, ch, flag; while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) { ch = readb(port->membase + MCFUART_URB); diff --git a/drivers/tty/serial/milbeaut_usio.c b/drivers/tty/serial/milbeaut_usio.c index 44988a2941b8..70a910085e93 100644 --- a/drivers/tty/serial/milbeaut_usio.c +++ b/drivers/tty/serial/milbeaut_usio.c @@ -148,8 +148,7 @@ static void mlb_usio_enable_ms(struct uart_port *port) static void mlb_usio_rx_chars(struct uart_port *port) { struct tty_port *ttyport = &port->state->port; - unsigned long flag = 0; - char ch = 0; + u8 flag = 0, ch = 0; u8 status; int max_count = 2; diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index a368f4293967..2ef10997df18 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -616,9 +616,8 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s) static void mxs_auart_rx_char(struct mxs_auart_port *s) { - int flag; u32 stat; - u8 c; + u8 c, flag; c = mxs_read(s, REG_DATA); stat = mxs_read(s, REG_STAT); diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 16ab7ea07fa3..2c11870fa894 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -442,7 +442,7 @@ static unsigned int check_modem_status(struct uart_omap_port *up) static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr) { - unsigned int flag; + u8 flag; /* * Read one data character out to avoid stalling the receiver according @@ -498,7 +498,7 @@ static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr) static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) { - unsigned char ch = 0; + u8 ch; if (!(lsr & UART_LSR_DR)) return; diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 444fa4b654ac..73c60f5ea027 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -90,7 +90,7 @@ static void serial_pxa_stop_rx(struct uart_port *port) static inline void receive_chars(struct uart_pxa_port *up, int *status) { - unsigned int ch, flag; + u8 ch, flag; int max_count = 256; do { diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c index 749b873a5d99..de220ac8ca54 100644 --- a/drivers/tty/serial/rp2.c +++ b/drivers/tty/serial/rp2.c @@ -401,14 +401,14 @@ static void rp2_rx_chars(struct rp2_uart_port *up) for (; bytes != 0; bytes--) { u32 byte = readw(up->base + RP2_DATA_BYTE) | RP2_DUMMY_READ; - char ch = byte & 0xff; + u8 ch = byte & 0xff; if (likely(!(byte & RP2_DATA_BYTE_EXCEPTION_MASK))) { if (!uart_handle_sysrq_char(&up->port, ch)) uart_insert_char(&up->port, byte, 0, ch, TTY_NORMAL); } else { - char flag = TTY_NORMAL; + u8 flag = TTY_NORMAL; if (byte & RP2_DATA_BYTE_BREAK_m) flag = TTY_BREAK; diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 55107bbc00ce..ad011f1e2f4d 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -180,7 +180,8 @@ static void sa1100_enable_ms(struct uart_port *port) static void sa1100_rx_chars(struct sa1100_port *sport) { - unsigned int status, ch, flg; + unsigned int status; + u8 ch, flg; status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | UTSR0_TO_SM(UART_GET_UTSR0(sport)); diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index b29e9dfd81a6..aa4a184f4a6c 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -759,9 +759,10 @@ finish: static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport) { struct uart_port *port = &ourport->port; - unsigned int ufcon, ch, flag, ufstat, uerstat; + unsigned int ufcon, ufstat, uerstat; unsigned int fifocnt = 0; int max_count = port->fifosize; + u8 ch, flag; while (max_count-- > 0) { /* diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index b6de0dc51f29..f3cd69346482 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c @@ -331,8 +331,9 @@ static void sbd_receive_chars(struct sbd_port *sport) { struct uart_port *uport = &sport->port; struct uart_icount *icount; - unsigned int status, ch, flag; + unsigned int status; int count; + u8 ch, flag; for (count = 16; count; count--) { status = read_sbdchn(sport, R_DUART_STATUS); diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 2e7e7c409cf2..cfffc730ba34 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -578,8 +578,9 @@ static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen, unsigned int iir) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); - unsigned int lsr = 0, ch, flag, bytes_read, i; + unsigned int lsr = 0, bytes_read, i; bool read_lsr = (iir == SC16IS7XX_IIR_RLSE_SRC) ? true : false; + u8 ch, flag; if (unlikely(rxlen >= sizeof(s->buf))) { dev_warn_ratelimited(port->dev, diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index 4f2fc5f7bb19..31ee46eba580 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -383,8 +383,7 @@ static void sccnxp_set_bit(struct uart_port *port, int sig, int state) static void sccnxp_handle_rx(struct uart_port *port) { - u8 sr; - unsigned int ch, flag; + u8 sr, ch, flag; for (;;) { sr = sccnxp_port_read(port, SCCNXP_SR_REG); diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 1cf08b33456c..813ae97159c4 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -434,10 +434,10 @@ static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) return 0; } -static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup, +static u8 tegra_uart_decode_rx_error(struct tegra_uart_port *tup, unsigned long lsr) { - char flag = TTY_NORMAL; + u8 flag = TTY_NORMAL; if (unlikely(lsr & TEGRA_UART_LSR_ANY)) { if (lsr & UART_LSR_OE) { @@ -642,9 +642,8 @@ static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, struct tty_port *port) { do { - char flag = TTY_NORMAL; unsigned long lsr = 0; - unsigned char ch; + u8 ch, flag = TTY_NORMAL; lsr = tegra_uart_read(tup, UART_LSR); if (!(lsr & UART_LSR_DR)) diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index eab387b01e36..be08fb6f749c 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -246,11 +246,10 @@ static void serial_txx9_initialize(struct uart_port *up) static inline void receive_chars(struct uart_port *up, unsigned int *status) { - unsigned char ch; unsigned int disr = *status; int max_count = 256; - char flag; unsigned int next_ignore_status_mask; + u8 ch, flag; do { ch = sio_in(up, TXX9_SIRFIFO); diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index 1f565a216e74..c00080f12cab 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -402,9 +402,9 @@ static char __ssp_receive_char(struct sifive_serial_port *ssp, char *is_empty) */ static void __ssp_receive_chars(struct sifive_serial_port *ssp) { - unsigned char ch; char is_empty; int c; + u8 ch; for (c = SIFIVE_RX_FIFO_DEPTH; c > 0; --c) { ch = __ssp_receive_char(ssp, &is_empty); diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index b58f51296ace..8f6fd1cd91d7 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -558,7 +558,7 @@ static void sprd_break_ctl(struct uart_port *port, int break_state) } static int handle_lsr_errors(struct uart_port *port, - unsigned int *flag, + u8 *flag, unsigned int *lsr) { int ret = 0; @@ -594,7 +594,8 @@ static inline void sprd_rx(struct uart_port *port) struct sprd_uart_port *sp = container_of(port, struct sprd_uart_port, port); struct tty_port *tty = &port->state->port; - unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT; + unsigned int lsr, max_count = SPRD_TIMEOUT; + u8 ch, flag; if (sp->rx_dma.enable) { sprd_uart_dma_irq(port); diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index aa471c9c24d9..387bc69bb1fe 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -250,7 +250,7 @@ static void asc_receive_chars(struct uart_port *port) struct tty_port *tport = &port->state->port; unsigned long status, mode; unsigned long c = 0; - char flag; + u8 flag; bool ignore_pe = false; /* diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index e9e11a259621..be47cd343cf6 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -321,7 +321,7 @@ static bool stm32_usart_pending_rx_pio(struct uart_port *port, u32 *sr) return false; } -static unsigned long stm32_usart_get_char_pio(struct uart_port *port) +static u8 stm32_usart_get_char_pio(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; @@ -338,10 +338,9 @@ static unsigned int stm32_usart_receive_chars_pio(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; - unsigned long c; unsigned int size = 0; u32 sr; - char flag; + u8 c, flag; while (stm32_usart_pending_rx_pio(port, &sr)) { sr |= USART_SR_DUMMY_RX; diff --git a/drivers/tty/serial/sunplus-uart.c b/drivers/tty/serial/sunplus-uart.c index 727942c43c45..3aacd5eb414c 100644 --- a/drivers/tty/serial/sunplus-uart.c +++ b/drivers/tty/serial/sunplus-uart.c @@ -231,7 +231,7 @@ static void transmit_chars(struct uart_port *port) static void receive_chars(struct uart_port *port) { unsigned int lsr = readl(port->membase + SUP_UART_LSR); - unsigned int ch, flag; + u8 ch, flag; do { ch = readl(port->membase + SUP_UART_DATA); diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index 730c648e32ff..65ca4da6e368 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c @@ -539,8 +539,9 @@ static void zs_receive_chars(struct zs_port *zport) struct uart_port *uport = &zport->port; struct zs_scc *scc = zport->scc; struct uart_icount *icount; - unsigned int avail, status, ch, flag; + unsigned int avail, status; int count; + u8 ch, flag; for (count = 16; count; count--) { spin_lock(&scc->zlock); -- cgit v1.2.3 From 51273792cb9be9a2f7bd9ef3e8237e2668067793 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 11 Jul 2023 18:05:16 +0200 Subject: serial: qcom-geni: use icc tag defines Use the Qualcomm interconnect defines rather than magic numbers for the icc tags also in the restore() PM callback. Signed-off-by: Johan Hovold Reviewed-by: Georgi Djakov Link: https://lore.kernel.org/r/20230711160516.30502-1-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 444c74eeab7d..88ed5bbe25a8 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1757,7 +1757,7 @@ static int qcom_geni_serial_sys_hib_resume(struct device *dev) private_data = uport->private_data; if (uart_console(uport)) { - geni_icc_set_tag(&port->se, 0x7); + geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS); geni_icc_set_bw(&port->se); ret = uart_resume_port(private_data->drv, uport); /* -- cgit v1.2.3 From 29e5c442e553cea180682d54ac0e2e95250fa668 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 24 Jul 2023 14:54:38 -0600 Subject: tty: Explicitly include correct DT includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring Acked-by: Uwe Kleine-König # for imx Link: https://lore.kernel.org/r/20230724205440.767071-1-robh@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_opal.c | 2 +- drivers/tty/serial/8250/8250_early.c | 1 - drivers/tty/serial/8250/8250_ingenic.c | 1 - drivers/tty/serial/8250/8250_omap.c | 1 - drivers/tty/serial/amba-pl011.c | 2 +- drivers/tty/serial/apbuart.c | 3 --- drivers/tty/serial/atmel_serial.c | 1 - drivers/tty/serial/fsl_linflexuart.c | 2 +- drivers/tty/serial/fsl_lpuart.c | 2 +- drivers/tty/serial/imx.c | 1 - drivers/tty/serial/lantiq.c | 3 ++- drivers/tty/serial/liteuart.c | 3 +-- drivers/tty/serial/ma35d1_serial.c | 2 +- drivers/tty/serial/mpc52xx_uart.c | 2 +- drivers/tty/serial/mps2-uart.c | 1 - drivers/tty/serial/mxs-auart.c | 2 +- drivers/tty/serial/pic32_uart.c | 1 - drivers/tty/serial/qcom_geni_serial.c | 1 - drivers/tty/serial/serial-tegra.c | 1 - drivers/tty/serial/sh-sci.c | 1 - drivers/tty/serial/sunhv.c | 4 ++-- drivers/tty/serial/sunsab.c | 3 ++- drivers/tty/serial/sunsu.c | 4 ++-- drivers/tty/serial/sunzilog.c | 4 ++-- drivers/tty/serial/tegra-tcu.c | 1 - drivers/tty/serial/uartlite.c | 3 --- drivers/tty/serial/ucc_uart.c | 3 ++- drivers/tty/serial/vt8500_serial.c | 2 +- 28 files changed, 21 insertions(+), 36 deletions(-) diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index 794c7b18aa06..992e199e0ea8 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 4299a8bd83d9..9837a27739fd 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 617b8ce60d6b..4c4c4da73ad0 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index d48a82f1634e..26dd089d8e82 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8bddc7470bcc..3dc9b0fcab1c 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 372db052573d..d7658f380838 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -22,9 +22,6 @@ #include #include #include -#include -#include -#include #include #include #include diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index ec54436969dc..88cdafa5ac54 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c index 6fc21b6684e6..f697751c2ad5 100644 --- a/drivers/tty/serial/fsl_linflexuart.c +++ b/drivers/tty/serial/fsl_linflexuart.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 4d80fae20177..e1a8d5415718 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -18,9 +18,9 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 7341d060f85c..3ed5083a7108 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index bcaa479608d8..3adb60c683f7 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c index 80de3a42b67b..d881cdd2a58f 100644 --- a/drivers/tty/serial/liteuart.c +++ b/drivers/tty/serial/liteuart.c @@ -11,8 +11,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/drivers/tty/serial/ma35d1_serial.c b/drivers/tty/serial/ma35d1_serial.c index 2604b4d9fb78..789593495a80 100644 --- a/drivers/tty/serial/ma35d1_serial.c +++ b/drivers/tty/serial/ma35d1_serial.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 384ca195e3d5..916507b8f31d 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/tty/serial/mps2-uart.c b/drivers/tty/serial/mps2-uart.c index 860d161fa594..5da88cbeec73 100644 --- a/drivers/tty/serial/mps2-uart.c +++ b/drivers/tty/serial/mps2-uart.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 2ef10997df18..8eeecf8ad359 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index 196a4e678451..e308d5022b3f 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 88ed5bbe25a8..a1c8dcd781da 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 813ae97159c4..056ed1f957ab 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 7c9457962a3d..115271d2f82d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 7d38c33ef506..c671d674bce4 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -17,11 +17,11 @@ #include #include #include -#include +#include +#include #include #include -#include #include #include diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 48b39fdb0397..40eeaf835bba 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -33,7 +33,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index fed052a0b931..58a4342ad0f9 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -37,11 +37,11 @@ #include #include #include -#include +#include +#include #include #include -#include #include #include diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 0fbeb3dbd843..c8c71c56264c 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -33,11 +33,11 @@ #include #endif #include -#include +#include +#include #include #include -#include #include #include diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c index 23500b342da7..65069daf36ec 100644 --- a/drivers/tty/serial/tegra-tcu.c +++ b/drivers/tty/serial/tegra-tcu.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 679574893ebe..b225a78f6175 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -20,9 +20,6 @@ #include #include #include -#include -#include -#include #include #include diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 404230c1ebb2..284b293fade6 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -17,15 +17,16 @@ */ #include +#include #include #include #include #include #include #include +#include #include #include -#include #include #include diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index cc9157df732f..32433e9b3e5f 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include /* -- cgit v1.2.3 From ad4484afe7de7869248b7c7a8e9722a62cb72bd0 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Mon, 3 Jul 2023 12:37:59 +0100 Subject: serial: tegra: Don't print error on probe deferral If the Tegra serial driver is probe before clocks are available then the following error is seen on boot: serial-tegra 3100000.serial: Couldn't get the clock This has been observed on Jetson AGX Orin. Fix this by calling dev_err_probe() instead of dev_err() to avoid printing an error on probe deferral. Signed-off-by: Jon Hunter Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20230703113759.75608-1-jonathanh@nvidia.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial-tegra.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 056ed1f957ab..f7f0841d60c9 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -1589,10 +1589,8 @@ static int tegra_uart_probe(struct platform_device *pdev) return PTR_ERR(u->membase); tup->uart_clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(tup->uart_clk)) { - dev_err(&pdev->dev, "Couldn't get the clock\n"); - return PTR_ERR(tup->uart_clk); - } + if (IS_ERR(tup->uart_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(tup->uart_clk), "Couldn't get the clock"); tup->rst = devm_reset_control_get_exclusive(&pdev->dev, "serial"); if (IS_ERR(tup->rst)) { -- cgit v1.2.3 From 328c79dd0e70da2126d5c122b0a74a1af93af730 Mon Sep 17 00:00:00 2001 From: "Rodríguez Barbarin, José Javier" Date: Wed, 5 Jul 2023 13:15:10 +0000 Subject: 8250_men_mcb: Add clockrate speed for G215/F215 boards Some F215 FPGA multifunction boards announce themselves as 215. This leads to a misconfigured clockrate. The F215 is the same board as G215 but with different cPCI interface so make them get the same configuration Co-developed-by: Jorge Sanjuan Garcia Signed-off-by: Jorge Sanjuan Garcia Signed-off-by: Javier Rodriguez Link: https://lore.kernel.org/r/20230705131423.30552-2-josejavier.rodriguez@duagon.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index f46ca13ff4aa..a2cdaeb61e00 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -37,10 +37,10 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev) clkval = 1041666; else if (strncmp(mdev->bus->name, "F216", 4) == 0) clkval = 1843200; - else if (strncmp(mdev->bus->name, "G215", 4) == 0) - clkval = 1843200; else if (strncmp(mdev->bus->name, "F210", 4) == 0) clkval = 115200; + else if (strstr(mdev->bus->name, "215")) + clkval = 1843200; else dev_info(&mdev->dev, "board not detected, using default uartclk\n"); -- cgit v1.2.3 From 2554e6ba28a25f00cf1258d984a695e7ae391af2 Mon Sep 17 00:00:00 2001 From: "Rodríguez Barbarin, José Javier" Date: Wed, 5 Jul 2023 13:15:12 +0000 Subject: 8250_men_mcb: Read num ports from register data. The IP Core Z025 and Z057 have a register where the amount of UART ports is specified. Such register is located at offset 0x40. This patch fixes the way the UART ports is calculated by reading the actual register. Additionally a refactor was needed to achieve this so we can keep track of the UART line and its offset which also improves the remove callback. Co-developed-by: Jorge Sanjuan Garcia Signed-off-by: Jorge Sanjuan Garcia Signed-off-by: Javier Rodriguez Link: https://lore.kernel.org/r/20230705131423.30552-3-josejavier.rodriguez@duagon.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 189 ++++++++++++++++++++++++--------- 1 file changed, 139 insertions(+), 50 deletions(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index a2cdaeb61e00..d6cfebb3ee8f 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -12,11 +12,42 @@ #define MEN_UART_ID_Z057 0x39 #define MEN_UART_ID_Z125 0x7d -#define MEN_UART_MEM_SIZE 0x10 +/* + * IP Cores Z025 and Z057 can have up to 4 UART + * The UARTs available are stored in a global + * register saved in physical address + 0x40 + * Is saved as follows: + * + * 7 0 + * +------+-------+-------+-------+-------+-------+-------+-------+ + * |UART4 | UART3 | UART2 | UART1 | U4irq | U3irq | U2irq | U1irq | + * +------+-------+-------+-------+-------+-------+-------+-------+ + */ +#define MEN_UART1_MASK 0x01 +#define MEN_UART2_MASK 0x02 +#define MEN_UART3_MASK 0x04 +#define MEN_UART4_MASK 0x08 + +#define MEN_Z125_UARTS_AVAILABLE 0x01 + +#define MEN_Z025_MAX_UARTS 4 +#define MEN_UART_MEM_SIZE 0x10 +#define MEM_UART_REGISTER_SIZE 0x01 +#define MEN_Z025_REGISTER_OFFSET 0x40 + +#define MEN_UART1_OFFSET 0 +#define MEN_UART2_OFFSET (MEN_UART1_OFFSET + MEN_UART_MEM_SIZE) +#define MEN_UART3_OFFSET (MEN_UART2_OFFSET + MEN_UART_MEM_SIZE) +#define MEN_UART4_OFFSET (MEN_UART3_OFFSET + MEN_UART_MEM_SIZE) + +#define MEN_READ_REGISTER(addr) readb((void *)addr) + +#define MAX_PORTS 4 struct serial_8250_men_mcb_data { - struct uart_8250_port uart; - int line; + int num_ports; + unsigned int line[MAX_PORTS]; + unsigned int offset[MAX_PORTS]; }; /* @@ -50,16 +81,82 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev) return clkval; } -static int get_num_ports(struct mcb_device *mdev, - void __iomem *membase) +static int read_uarts_available_from_register(void __iomem *membase, + u8 *uarts_available) +{ + void __iomem *mem; + int reg_value; + + mem = membase + MEN_Z025_REGISTER_OFFSET; + + reg_value = MEN_READ_REGISTER(membase); + + *uarts_available = reg_value >> 4; + + return 0; +} + +static int read_serial_data(struct mcb_device *mdev, + void __iomem *membase, + struct serial_8250_men_mcb_data *serial_data) +{ + u8 uarts_available; + int count = 0; + int mask; + int res; + int i; + + res = read_uarts_available_from_register(membase, &uarts_available); + if (res < 0) + return res; + + for (i = 0; i < MAX_PORTS; i++) { + mask = 0x1 << i; + switch (uarts_available & mask) { + case MEN_UART1_MASK: + serial_data->offset[count] = MEN_UART1_OFFSET; + count++; + break; + case MEN_UART2_MASK: + serial_data->offset[count] = MEN_UART2_OFFSET; + count++; + break; + case MEN_UART3_MASK: + serial_data->offset[count] = MEN_UART3_OFFSET; + count++; + break; + case MEN_UART4_MASK: + serial_data->offset[count] = MEN_UART4_OFFSET; + count++; + break; + default: + return -EINVAL; + } + } + + if (count <= 0 || count > MAX_PORTS) { + dev_err(&mdev->dev, "unexpected number of ports: %u\n", + count); + return -ENODEV; + } + + serial_data->num_ports = count; + + return 0; +} + +static int init_serial_data(struct mcb_device *mdev, + void __iomem *membase, + struct serial_8250_men_mcb_data *serial_data) { switch (mdev->id) { case MEN_UART_ID_Z125: - return 1U; + serial_data->num_ports = 1; + serial_data->offset[0] = 0; + return 0; case MEN_UART_ID_Z025: - return readb(membase) >> 4; case MEN_UART_ID_Z057: - return 4U; + return read_serial_data(mdev, membase, serial_data); default: dev_err(&mdev->dev, "no supported device!\n"); return -ENODEV; @@ -69,11 +166,12 @@ static int get_num_ports(struct mcb_device *mdev, static int serial_8250_men_mcb_probe(struct mcb_device *mdev, const struct mcb_device_id *id) { + struct uart_8250_port uart; struct serial_8250_men_mcb_data *data; struct resource *mem; - int num_ports; int i; void __iomem *membase; + int res; mem = mcb_get_resource(mdev, IORESOURCE_MEM); if (mem == NULL) @@ -82,49 +180,46 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, if (IS_ERR(membase)) return PTR_ERR_OR_ZERO(membase); - num_ports = get_num_ports(mdev, membase); - - dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n", - mdev->id, num_ports); - - if (num_ports <= 0 || num_ports > 4) { - dev_err(&mdev->dev, "unexpected number of ports: %u\n", - num_ports); - return -ENODEV; - } - - data = devm_kcalloc(&mdev->dev, num_ports, + data = devm_kzalloc(&mdev->dev, sizeof(struct serial_8250_men_mcb_data), GFP_KERNEL); if (!data) return -ENOMEM; + res = init_serial_data(mdev, membase, data); + if (res < 0) + return res; + + dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n", + mdev->id, data->num_ports); + mcb_set_drvdata(mdev, data); - for (i = 0; i < num_ports; i++) { - data[i].uart.port.dev = mdev->dma_dev; - spin_lock_init(&data[i].uart.port.lock); - - data[i].uart.port.type = PORT_16550; - data[i].uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ - | UPF_FIXED_TYPE; - data[i].uart.port.iotype = UPIO_MEM; - data[i].uart.port.uartclk = men_lookup_uartclk(mdev); - data[i].uart.port.regshift = 0; - data[i].uart.port.irq = mcb_get_irq(mdev); - data[i].uart.port.membase = membase; - data[i].uart.port.fifosize = 60; - data[i].uart.port.mapbase = (unsigned long) mem->start - + i * MEN_UART_MEM_SIZE; - data[i].uart.port.iobase = data[i].uart.port.mapbase; + for (i = 0; i < data->num_ports; i++) { + uart.port.dev = mdev->dma_dev; + spin_lock_init(&uart.port.lock); + + uart.port.type = PORT_16550; + uart.port.flags = UPF_SKIP_TEST | + UPF_SHARE_IRQ | + UPF_FIXED_TYPE; + uart.port.iotype = UPIO_MEM; + uart.port.uartclk = men_lookup_uartclk(mdev); + uart.port.regshift = 0; + uart.port.irq = mcb_get_irq(mdev); + uart.port.membase = membase; + uart.port.fifosize = 60; + uart.port.mapbase = (unsigned long) mem->start + + data->offset[i]; + uart.port.iobase = uart.port.mapbase; /* ok, register the port */ - data[i].line = serial8250_register_8250_port(&data[i].uart); - if (data[i].line < 0) { + data->line[i] = serial8250_register_8250_port(&uart); + if (data->line[i] < 0) { dev_err(&mdev->dev, "unable to register UART port\n"); - return data[i].line; + return data->line[i]; } - dev_info(&mdev->dev, "found MCB UART: ttyS%d\n", data[i].line); + dev_info(&mdev->dev, "found MCB UART: ttyS%d\n", data->line[i]); } return 0; @@ -132,20 +227,14 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, static void serial_8250_men_mcb_remove(struct mcb_device *mdev) { - int num_ports, i; + int i; struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev); if (!data) return; - num_ports = get_num_ports(mdev, data[0].uart.port.membase); - if (num_ports <= 0 || num_ports > 4) { - dev_err(&mdev->dev, "error retrieving number of ports!\n"); - return; - } - - for (i = 0; i < num_ports; i++) - serial8250_unregister_port(data[i].line); + for (i = 0; i < data->num_ports; i++) + serial8250_unregister_port(data->line[i]); } static const struct mcb_device_id serial_8250_men_mcb_ids[] = { -- cgit v1.2.3 From c563831ba879480ea16afb56fb2f81a0a0eb17a6 Mon Sep 17 00:00:00 2001 From: "Rodríguez Barbarin, José Javier" Date: Wed, 5 Jul 2023 13:15:14 +0000 Subject: 8250_men_mcb: Make UART config auto configurable The UART ports created by this driver were not usable out of the box, so let the configuration be handled by the 8250 UART subsystem. This makes the implementation simpler and the UART port more usable. The 8250 UART subsystem will take care of requesting the memory resources, but the driver needs to first read the register where the num ports is set, so a request of the resource is needed before registering the UART port. Co-developed-by: Jorge Sanjuan Garcia Signed-off-by: Jorge Sanjuan Garcia Signed-off-by: Javier Rodriguez Link: https://lore.kernel.org/r/20230705131423.30552-4-josejavier.rodriguez@duagon.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 43 +++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index d6cfebb3ee8f..c3143ffddea0 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -81,15 +81,28 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev) return clkval; } -static int read_uarts_available_from_register(void __iomem *membase, +static int read_uarts_available_from_register(struct resource *mem_res, u8 *uarts_available) { void __iomem *mem; int reg_value; - mem = membase + MEN_Z025_REGISTER_OFFSET; + if (!request_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET, + MEM_UART_REGISTER_SIZE, KBUILD_MODNAME)) { + return -EBUSY; + } + + mem = ioremap(mem_res->start + MEN_Z025_REGISTER_OFFSET, + MEM_UART_REGISTER_SIZE); + if (IS_ERR(mem)) + return -ENOMEM; + + reg_value = MEN_READ_REGISTER(mem); + + iounmap(mem); - reg_value = MEN_READ_REGISTER(membase); + release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET, + MEM_UART_REGISTER_SIZE); *uarts_available = reg_value >> 4; @@ -97,7 +110,7 @@ static int read_uarts_available_from_register(void __iomem *membase, } static int read_serial_data(struct mcb_device *mdev, - void __iomem *membase, + struct resource *mem_res, struct serial_8250_men_mcb_data *serial_data) { u8 uarts_available; @@ -106,7 +119,7 @@ static int read_serial_data(struct mcb_device *mdev, int res; int i; - res = read_uarts_available_from_register(membase, &uarts_available); + res = read_uarts_available_from_register(mem_res, &uarts_available); if (res < 0) return res; @@ -146,7 +159,7 @@ static int read_serial_data(struct mcb_device *mdev, } static int init_serial_data(struct mcb_device *mdev, - void __iomem *membase, + struct resource *mem_res, struct serial_8250_men_mcb_data *serial_data) { switch (mdev->id) { @@ -156,7 +169,7 @@ static int init_serial_data(struct mcb_device *mdev, return 0; case MEN_UART_ID_Z025: case MEN_UART_ID_Z057: - return read_serial_data(mdev, membase, serial_data); + return read_serial_data(mdev, mem_res, serial_data); default: dev_err(&mdev->dev, "no supported device!\n"); return -ENODEV; @@ -170,15 +183,11 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, struct serial_8250_men_mcb_data *data; struct resource *mem; int i; - void __iomem *membase; int res; mem = mcb_get_resource(mdev, IORESOURCE_MEM); if (mem == NULL) return -ENXIO; - membase = devm_ioremap_resource(&mdev->dev, mem); - if (IS_ERR(membase)) - return PTR_ERR_OR_ZERO(membase); data = devm_kzalloc(&mdev->dev, sizeof(struct serial_8250_men_mcb_data), @@ -186,7 +195,7 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, if (!data) return -ENOMEM; - res = init_serial_data(mdev, membase, data); + res = init_serial_data(mdev, mem, data); if (res < 0) return res; @@ -196,22 +205,18 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, mcb_set_drvdata(mdev, data); for (i = 0; i < data->num_ports; i++) { - uart.port.dev = mdev->dma_dev; + memset(&uart, 0, sizeof(struct uart_8250_port)); spin_lock_init(&uart.port.lock); - uart.port.type = PORT_16550; uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | - UPF_FIXED_TYPE; + UPF_BOOT_AUTOCONF | + UPF_IOREMAP; uart.port.iotype = UPIO_MEM; uart.port.uartclk = men_lookup_uartclk(mdev); - uart.port.regshift = 0; uart.port.irq = mcb_get_irq(mdev); - uart.port.membase = membase; - uart.port.fifosize = 60; uart.port.mapbase = (unsigned long) mem->start + data->offset[i]; - uart.port.iobase = uart.port.mapbase; /* ok, register the port */ data->line[i] = serial8250_register_8250_port(&uart); -- cgit v1.2.3 From b6092f36a56866e81afcea0530cc84963ebb9bf6 Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Wed, 5 Jul 2023 21:18:27 +0300 Subject: tty: serial: meson: use dev_err_probe Use dev_err_probe() helper for error checking and standard logging. It makes the driver's probe() function a little bit shorter. Signed-off-by: Dmitry Rokosov Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20230705181833.16137-2-ddrokosov@sberdevices.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 2501db5a7aaf..bca54f3d92a1 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -726,8 +726,8 @@ static int meson_uart_probe(struct platform_device *pdev) of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize); if (meson_ports[pdev->id]) { - dev_err(&pdev->dev, "port %d already allocated\n", pdev->id); - return -EBUSY; + return dev_err_probe(&pdev->dev, -EBUSY, + "port %d already allocated\n", pdev->id); } port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL); -- cgit v1.2.3 From bcb5645f99ef93b3cad3cdb7937eb4b2cecfd560 Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Wed, 5 Jul 2023 21:18:28 +0300 Subject: tty: serial: meson: redesign the module to platform_driver Actually, the meson_uart module is already a platform_driver, but it is currently registered manually and the uart core registration is run outside the probe() scope, which results in some restrictions. For instance, it is not possible to communicate with the OF subsystem because it requires an initialized device object. To address this issue, apply module_platform_driver() instead of direct module init/exit routines. Additionally, move uart_register_driver() to the driver probe(), and destroy manual console registration because it's already run in the uart_register_driver() flow. Signed-off-by: Dmitry Rokosov Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20230705181833.16137-3-ddrokosov@sberdevices.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 51 ++++++++++++----------------------------- 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index bca54f3d92a1..dcf994a11a21 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -621,12 +621,6 @@ static struct console meson_serial_console = { .data = &meson_uart_driver, }; -static int __init meson_serial_console_init(void) -{ - register_console(&meson_serial_console); - return 0; -} - static void meson_serial_early_console_write(struct console *co, const char *s, u_int count) @@ -652,9 +646,6 @@ OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", #define MESON_SERIAL_CONSOLE (&meson_serial_console) #else -static int __init meson_serial_console_init(void) { - return 0; -} #define MESON_SERIAL_CONSOLE NULL #endif @@ -738,6 +729,13 @@ static int meson_uart_probe(struct platform_device *pdev) if (ret) return ret; + if (!meson_uart_driver.state) { + ret = uart_register_driver(&meson_uart_driver); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "can't register uart driver\n"); + } + port->iotype = UPIO_MEM; port->mapbase = res_mem->start; port->mapsize = resource_size(res_mem); @@ -776,6 +774,13 @@ static int meson_uart_remove(struct platform_device *pdev) uart_remove_one_port(&meson_uart_driver, port); meson_ports[pdev->id] = NULL; + for (int id = 0; id < AML_UART_PORT_NUM; id++) + if (meson_ports[id]) + return 0; + + /* No more available uart ports, unregister uart driver */ + uart_unregister_driver(&meson_uart_driver); + return 0; } @@ -809,33 +814,7 @@ static struct platform_driver meson_uart_platform_driver = { }, }; -static int __init meson_uart_init(void) -{ - int ret; - - ret = meson_serial_console_init(); - if (ret) - return ret; - - ret = uart_register_driver(&meson_uart_driver); - if (ret) - return ret; - - ret = platform_driver_register(&meson_uart_platform_driver); - if (ret) - uart_unregister_driver(&meson_uart_driver); - - return ret; -} - -static void __exit meson_uart_exit(void) -{ - platform_driver_unregister(&meson_uart_platform_driver); - uart_unregister_driver(&meson_uart_driver); -} - -module_init(meson_uart_init); -module_exit(meson_uart_exit); +module_platform_driver(meson_uart_platform_driver); MODULE_AUTHOR("Carlo Caione "); MODULE_DESCRIPTION("Amlogic Meson serial port driver"); -- cgit v1.2.3 From e71aab9d613242bbb262f2344e377ecbc892df41 Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Wed, 5 Jul 2023 21:18:29 +0300 Subject: tty: serial: meson: apply ttyS devname instead of ttyAML for new SoCs It is worth noting that the devname ttyS is a widely recognized tty name and is commonly used by many uart device drivers. Given the established usage and compatibility concerns, it may not be feasible to change the devname for older SoCs. However, for new definitions, it is acceptable and even recommended to use a new devname to help ensure clarity and avoid any potential conflicts on lower or upper software levels. For more information please refer to IRC discussion at [1]. Links: [1]: https://libera.irclog.whitequark.org/linux-amlogic/2023-07-03 Signed-off-by: Dmitry Rokosov Link: https://lore.kernel.org/r/20230705181833.16137-4-ddrokosov@sberdevices.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 82 ++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index dcf994a11a21..ad0748a10db7 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -72,16 +72,22 @@ #define AML_UART_PORT_NUM 12 #define AML_UART_PORT_OFFSET 6 -#define AML_UART_DEV_NAME "ttyAML" #define AML_UART_POLL_USEC 5 #define AML_UART_TIMEOUT_USEC 10000 -static struct uart_driver meson_uart_driver; +#define MESON_UART_DRIVER(_devname) meson_uart_driver_##_devname + +#define MESON_UART_DRIVER_DECLARE(_devname) \ + static struct uart_driver MESON_UART_DRIVER(_devname) + +MESON_UART_DRIVER_DECLARE(ttyAML); +MESON_UART_DRIVER_DECLARE(ttyS); static struct uart_port *meson_ports[AML_UART_PORT_NUM]; struct meson_uart_data { + struct uart_driver *uart_driver; bool has_xtal_div2; }; @@ -611,15 +617,21 @@ static int meson_serial_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -static struct console meson_serial_console = { - .name = AML_UART_DEV_NAME, - .write = meson_serial_console_write, - .device = uart_console_device, - .setup = meson_serial_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &meson_uart_driver, -}; +#define MESON_SERIAL_CONSOLE(_devname) meson_serial_console_##_devname + +#define MESON_SERIAL_CONSOLE_DEFINE(_devname) \ + static struct console MESON_SERIAL_CONSOLE(_devname) = { \ + .name = __stringify(_devname), \ + .write = meson_serial_console_write, \ + .device = uart_console_device, \ + .setup = meson_serial_console_setup, \ + .flags = CON_PRINTBUFFER, \ + .index = -1, \ + .data = &MESON_UART_DRIVER(_devname), \ + } + +MESON_SERIAL_CONSOLE_DEFINE(ttyAML); +MESON_SERIAL_CONSOLE_DEFINE(ttyS); static void meson_serial_early_console_write(struct console *co, const char *s, @@ -644,18 +656,22 @@ meson_serial_early_console_setup(struct earlycon_device *device, const char *opt OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", meson_serial_early_console_setup); -#define MESON_SERIAL_CONSOLE (&meson_serial_console) +#define MESON_SERIAL_CONSOLE_PTR(_devname) (&MESON_SERIAL_CONSOLE(_devname)) #else -#define MESON_SERIAL_CONSOLE NULL +#define MESON_SERIAL_CONSOLE_PTR(_devname) (NULL) #endif -static struct uart_driver meson_uart_driver = { - .owner = THIS_MODULE, - .driver_name = "meson_uart", - .dev_name = AML_UART_DEV_NAME, - .nr = AML_UART_PORT_NUM, - .cons = MESON_SERIAL_CONSOLE, -}; +#define MESON_UART_DRIVER_DEFINE(_devname) \ + static struct uart_driver MESON_UART_DRIVER(_devname) = { \ + .owner = THIS_MODULE, \ + .driver_name = "meson_uart", \ + .dev_name = __stringify(_devname), \ + .nr = AML_UART_PORT_NUM, \ + .cons = MESON_SERIAL_CONSOLE_PTR(_devname), \ + } + +MESON_UART_DRIVER_DEFINE(ttyAML); +MESON_UART_DRIVER_DEFINE(ttyS); static int meson_uart_probe_clocks(struct platform_device *pdev, struct uart_port *port) @@ -681,8 +697,16 @@ static int meson_uart_probe_clocks(struct platform_device *pdev, return 0; } +static struct uart_driver *meson_uart_current(const struct meson_uart_data *pd) +{ + return (pd && pd->uart_driver) ? + pd->uart_driver : &MESON_UART_DRIVER(ttyAML); +} + static int meson_uart_probe(struct platform_device *pdev) { + const struct meson_uart_data *priv_data; + struct uart_driver *uart_driver; struct resource *res_mem; struct uart_port *port; u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */ @@ -729,8 +753,12 @@ static int meson_uart_probe(struct platform_device *pdev) if (ret) return ret; - if (!meson_uart_driver.state) { - ret = uart_register_driver(&meson_uart_driver); + priv_data = device_get_match_data(&pdev->dev); + + uart_driver = meson_uart_current(priv_data); + + if (!uart_driver->state) { + ret = uart_register_driver(uart_driver); if (ret) return dev_err_probe(&pdev->dev, ret, "can't register uart driver\n"); @@ -748,7 +776,7 @@ static int meson_uart_probe(struct platform_device *pdev) port->x_char = 0; port->ops = &meson_uart_ops; port->fifosize = fifosize; - port->private_data = (void *)device_get_match_data(&pdev->dev); + port->private_data = (void *)priv_data; meson_ports[pdev->id] = port; platform_set_drvdata(pdev, port); @@ -759,7 +787,7 @@ static int meson_uart_probe(struct platform_device *pdev) meson_uart_release_port(port); } - ret = uart_add_one_port(&meson_uart_driver, port); + ret = uart_add_one_port(uart_driver, port); if (ret) meson_ports[pdev->id] = NULL; @@ -768,10 +796,12 @@ static int meson_uart_probe(struct platform_device *pdev) static int meson_uart_remove(struct platform_device *pdev) { + struct uart_driver *uart_driver; struct uart_port *port; port = platform_get_drvdata(pdev); - uart_remove_one_port(&meson_uart_driver, port); + uart_driver = meson_uart_current(port->private_data); + uart_remove_one_port(uart_driver, port); meson_ports[pdev->id] = NULL; for (int id = 0; id < AML_UART_PORT_NUM; id++) @@ -779,7 +809,7 @@ static int meson_uart_remove(struct platform_device *pdev) return 0; /* No more available uart ports, unregister uart driver */ - uart_unregister_driver(&meson_uart_driver); + uart_unregister_driver(uart_driver); return 0; } -- cgit v1.2.3 From bd86980b5113e3bf59ad096c49bf5c39dbca8880 Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Wed, 5 Jul 2023 21:18:30 +0300 Subject: tty: serial: meson: introduce separate uart_data for S4 SoC family In order to use the correct devname value for the S4 SoC family, it is imperative that we implement separate uart_data. Unlike the legacy g12a architecture, the S4 architecture should employ the use of 'ttyS' devname. Signed-off-by: Dmitry Rokosov Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20230705181833.16137-5-ddrokosov@sberdevices.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index ad0748a10db7..6a63184b8091 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -818,6 +818,11 @@ static struct meson_uart_data meson_g12a_uart_data = { .has_xtal_div2 = true, }; +static struct meson_uart_data meson_s4_uart_data = { + .uart_driver = &MESON_UART_DRIVER(ttyS), + .has_xtal_div2 = true, +}; + static const struct of_device_id meson_uart_dt_match[] = { { .compatible = "amlogic,meson6-uart" }, { .compatible = "amlogic,meson8-uart" }, @@ -829,7 +834,7 @@ static const struct of_device_id meson_uart_dt_match[] = { }, { .compatible = "amlogic,meson-s4-uart", - .data = (void *)&meson_g12a_uart_data, + .data = (void *)&meson_s4_uart_data, }, { /* sentinel */ }, }; -- cgit v1.2.3 From 5651f657097c1ad9674651bee91425a8bb9d5b9a Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Wed, 5 Jul 2023 21:18:31 +0300 Subject: tty: serial: meson: add independent uart_data for A1 SoC family Implement separate uart_data to ensure proper devname value for the A1 SoC family. Use 'ttyS' devname, as required by the A1 architecture, instead of the legacy gx architecture. Signed-off-by: Dmitry Rokosov Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20230705181833.16137-6-ddrokosov@sberdevices.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 6a63184b8091..84cf10b0ca5c 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -818,6 +818,11 @@ static struct meson_uart_data meson_g12a_uart_data = { .has_xtal_div2 = true, }; +static struct meson_uart_data meson_a1_uart_data = { + .uart_driver = &MESON_UART_DRIVER(ttyS), + .has_xtal_div2 = false, +}; + static struct meson_uart_data meson_s4_uart_data = { .uart_driver = &MESON_UART_DRIVER(ttyS), .has_xtal_div2 = true, @@ -836,6 +841,10 @@ static const struct of_device_id meson_uart_dt_match[] = { .compatible = "amlogic,meson-s4-uart", .data = (void *)&meson_s4_uart_data, }, + { + .compatible = "amlogic,meson-a1-uart", + .data = (void *)&meson_a1_uart_data, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, meson_uart_dt_match); -- cgit v1.2.3 From dd825a4d91dbd1cce058e9fcddf7d8a10738524a Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Wed, 5 Jul 2023 21:18:32 +0300 Subject: dt-bindings: serial: amlogic,meson-uart: support Amlogic A1 Introduce meson uart serial bindings for A1 SoC family. Signed-off-by: Dmitry Rokosov Acked-by: Rob Herring Link: https://lore.kernel.org/r/20230705181833.16137-7-ddrokosov@sberdevices.ru Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml index 01ec45b3b406..f1ae8c4934d9 100644 --- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml +++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml @@ -33,6 +33,7 @@ properties: - amlogic,meson8b-uart - amlogic,meson-gx-uart - amlogic,meson-s4-uart + - amlogic,meson-a1-uart - const: amlogic,meson-ao-uart - description: Always-on power domain UART controller on G12A SoCs items: @@ -46,6 +47,7 @@ properties: - amlogic,meson8b-uart - amlogic,meson-gx-uart - amlogic,meson-s4-uart + - amlogic,meson-a1-uart - description: Everything-Else power domain UART controller on G12A SoCs items: - const: amlogic,meson-g12a-uart -- cgit v1.2.3 From 6d71ded2723b8534819a3a2e305145e26d2bd53e Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Wed, 5 Jul 2023 21:18:33 +0300 Subject: arm64: dts: meson: a1: change uart compatible string In the current implementation, the meson-a1 configuration incorporates a unique compatibility tag "amlogic,meson-a1-uart' within the meson-uart driver due to its usage of the new console device name "ttyS". Consequently, the previous compatibility tag designated for the 'amlogic,meson-gx-uart' configuration has become obsolete and is no longer relevant to the current setup. Signed-off-by: Dmitry Rokosov Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20230705181833.16137-8-ddrokosov@sberdevices.ru Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi index c8f344596285..96225c421194 100644 --- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi @@ -108,7 +108,7 @@ }; uart_AO: serial@1c00 { - compatible = "amlogic,meson-gx-uart", + compatible = "amlogic,meson-a1-uart", "amlogic,meson-ao-uart"; reg = <0x0 0x1c00 0x0 0x18>; interrupts = ; @@ -118,7 +118,7 @@ }; uart_AO_B: serial@2000 { - compatible = "amlogic,meson-gx-uart", + compatible = "amlogic,meson-a1-uart", "amlogic,meson-ao-uart"; reg = <0x0 0x2000 0x0 0x18>; interrupts = ; -- cgit v1.2.3 From 67b7a397b2d0dcfcc9aad03d9397b324f6e44d56 Mon Sep 17 00:00:00 2001 From: Duje Mihanović Date: Fri, 21 Jul 2023 22:37:43 +0200 Subject: tty: serial: 8250: Define earlycon for mrvl,mmp-uart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mrvl,pxa-uart already supports earlycon and both compatible strings use the same driver, so there's no reason for mmp-uart to not have earlycon as well. Signed-off-by: Duje Mihanović Link: https://lore.kernel.org/r/20230721210042.21535-2-duje.mihanovic@skole.hr Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pxa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c index 28b341f602c6..a5b3ea27fc90 100644 --- a/drivers/tty/serial/8250/8250_pxa.c +++ b/drivers/tty/serial/8250/8250_pxa.c @@ -183,6 +183,7 @@ static int __init early_serial_pxa_setup(struct earlycon_device *device, return early_serial8250_setup(device, NULL); } OF_EARLYCON_DECLARE(early_pxa, "mrvl,pxa-uart", early_serial_pxa_setup); +OF_EARLYCON_DECLARE(mmp, "mrvl,mmp-uart", early_serial_pxa_setup); #endif MODULE_AUTHOR("Sergei Ianovich"); -- cgit v1.2.3 From 290c80069c731e81f4949bfa34fedc8d8a5a793e Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Wed, 5 Jul 2023 09:56:02 +0800 Subject: dt-bindings: serial: fsl-lpuart: correct imx93-lpuart dt-binding item Correct the fsl,imx93-lpuart dt-binding item, imx93/imx8ulp add some new features based on imx7ulp lpuart, so need to add "fsl,imx8ulp-lpuart" for imx93 to enable those new features. Signed-off-by: Sherry Sun Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230705015602.29569-4-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/fsl-lpuart.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml b/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml index 93062403276b..3a5b59f5d3e3 100644 --- a/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml +++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml @@ -25,9 +25,13 @@ properties: - fsl,imxrt1050-lpuart - items: - enum: - - fsl,imx93-lpuart - fsl,imx8ulp-lpuart - const: fsl,imx7ulp-lpuart + - items: + - enum: + - fsl,imx93-lpuart + - const: fsl,imx8ulp-lpuart + - const: fsl,imx7ulp-lpuart - items: - enum: - fsl,imx8qm-lpuart -- cgit v1.2.3 From 9cb31a2824f9399930ef0c9c449cec258bac66e4 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Mon, 10 Jul 2023 09:38:56 +0800 Subject: tty: serial: fsl_lpuart: move the lpuart32_int() below Move the lpuart32_int() below lpuart_copy_rx_to_tty(), this is a preparation patch for the next patch to avoid the function declaration, no actual functional changes. Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20230710013857.7396-2-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index e1a8d5415718..159a2de509f3 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1064,26 +1064,6 @@ static irqreturn_t lpuart_int(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t lpuart32_int(int irq, void *dev_id) -{ - struct lpuart_port *sport = dev_id; - unsigned long sts, rxcount; - - sts = lpuart32_read(&sport->port, UARTSTAT); - rxcount = lpuart32_read(&sport->port, UARTWATER); - rxcount = rxcount >> UARTWATER_RXCNT_OFF; - - if ((sts & UARTSTAT_RDRF || rxcount > 0) && !sport->lpuart_dma_rx_use) - lpuart32_rxint(sport); - - if ((sts & UARTSTAT_TDRE) && !sport->lpuart_dma_tx_use) - lpuart32_txint(sport); - - lpuart32_write(&sport->port, sts, UARTSTAT); - return IRQ_HANDLED; -} - - static inline void lpuart_handle_sysrq_chars(struct uart_port *port, unsigned char *p, int count) { @@ -1276,6 +1256,25 @@ static void lpuart_dma_rx_complete(void *arg) lpuart_copy_rx_to_tty(sport); } +static irqreturn_t lpuart32_int(int irq, void *dev_id) +{ + struct lpuart_port *sport = dev_id; + unsigned long sts, rxcount; + + sts = lpuart32_read(&sport->port, UARTSTAT); + rxcount = lpuart32_read(&sport->port, UARTWATER); + rxcount = rxcount >> UARTWATER_RXCNT_OFF; + + if ((sts & UARTSTAT_RDRF || rxcount > 0) && !sport->lpuart_dma_rx_use) + lpuart32_rxint(sport); + + if ((sts & UARTSTAT_TDRE) && !sport->lpuart_dma_tx_use) + lpuart32_txint(sport); + + lpuart32_write(&sport->port, sts, UARTSTAT); + return IRQ_HANDLED; +} + /* * Timer function to simulate the hardware EOP (End Of Package) event. * The timer callback is to check for new RX data and copy to TTY buffer. -- cgit v1.2.3 From d9219528fab995c7cae79313867a8a92ee8e1f28 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Mon, 10 Jul 2023 09:38:57 +0800 Subject: tty: serial: fsl_lpuart: add IDLE interrupt support for rx_dma on imx7ulp/imx8ulp/imx8qxp Add IDLE interrupt support for receive dma on imx7ulp/imx8ulp/imx8qxp platforms to replace the receive dma timer function, because the receive dma timer has bigger latency than idle interrupt triggering, which may cause the Bluetooth Firmware download timeout on Android platform(it has a limited FW download time window). Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20230710013857.7396-3-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 44 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 159a2de509f3..5c889c65d8ea 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -288,6 +288,7 @@ struct lpuart_port { wait_queue_head_t dma_wait; bool is_cs7; /* Set to true when character size is 7 */ /* and the parity is enabled */ + bool dma_idle_int; }; struct lpuart_soc_data { @@ -1246,7 +1247,8 @@ exit: spin_unlock_irqrestore(&sport->port.lock, flags); tty_flip_buffer_push(port); - mod_timer(&sport->lpuart_timer, jiffies + sport->dma_rx_timeout); + if (!sport->dma_idle_int) + mod_timer(&sport->lpuart_timer, jiffies + sport->dma_rx_timeout); } static void lpuart_dma_rx_complete(void *arg) @@ -1256,6 +1258,28 @@ static void lpuart_dma_rx_complete(void *arg) lpuart_copy_rx_to_tty(sport); } +static void lpuart32_dma_idleint(struct lpuart_port *sport) +{ + enum dma_status dmastat; + struct dma_chan *chan = sport->dma_rx_chan; + struct circ_buf *ring = &sport->rx_ring; + struct dma_tx_state state; + int count = 0; + + dmastat = dmaengine_tx_status(chan, sport->dma_rx_cookie, &state); + if (dmastat == DMA_ERROR) { + dev_err(sport->port.dev, "Rx DMA transfer failed!\n"); + return; + } + + ring->head = sport->rx_sgl.length - state.residue; + count = CIRC_CNT(ring->head, ring->tail, sport->rx_sgl.length); + + /* Check if new data received before copying */ + if (count) + lpuart_copy_rx_to_tty(sport); +} + static irqreturn_t lpuart32_int(int irq, void *dev_id) { struct lpuart_port *sport = dev_id; @@ -1271,6 +1295,9 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id) if ((sts & UARTSTAT_TDRE) && !sport->lpuart_dma_tx_use) lpuart32_txint(sport); + if ((sts & UARTSTAT_IDLE) && sport->lpuart_dma_rx_use && sport->dma_idle_int) + lpuart32_dma_idleint(sport); + lpuart32_write(&sport->port, sts, UARTSTAT); return IRQ_HANDLED; } @@ -1391,6 +1418,12 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport) unsigned long temp = lpuart32_read(&sport->port, UARTBAUD); lpuart32_write(&sport->port, temp | UARTBAUD_RDMAE, UARTBAUD); + + if (sport->dma_idle_int) { + unsigned long ctrl = lpuart32_read(&sport->port, UARTCTRL); + + lpuart32_write(&sport->port, ctrl | UARTCTRL_ILIE, UARTCTRL); + } } else { writeb(readb(sport->port.membase + UARTCR5) | UARTCR5_RDMAS, sport->port.membase + UARTCR5); @@ -1406,7 +1439,9 @@ static void lpuart_dma_rx_free(struct uart_port *port) struct dma_chan *chan = sport->dma_rx_chan; dmaengine_terminate_sync(chan); - del_timer_sync(&sport->lpuart_timer); + if (!sport->dma_idle_int) + del_timer_sync(&sport->lpuart_timer); + dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); kfree(sport->rx_ring.buf); sport->rx_ring.tail = 0; @@ -1668,6 +1703,9 @@ static void lpuart32_setup_watermark_enable(struct lpuart_port *sport) static void rx_dma_timer_init(struct lpuart_port *sport) { + if (sport->dma_idle_int) + return; + timer_setup(&sport->lpuart_timer, lpuart_timer_func, 0); sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout; add_timer(&sport->lpuart_timer); @@ -2821,6 +2859,8 @@ static int lpuart_probe(struct platform_device *pdev) sport->port.type = PORT_LPUART; sport->devtype = sdata->devtype; sport->rx_watermark = sdata->rx_watermark; + sport->dma_idle_int = is_imx7ulp_lpuart(sport) || is_imx8ulp_lpuart(sport) || + is_imx8qxp_lpuart(sport); ret = platform_get_irq(pdev, 0); if (ret < 0) return ret; -- cgit v1.2.3 From 8ece7b754bc34ffd7fcc8269ccb9128e72ca76d8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 14 Jul 2023 15:02:13 +0200 Subject: serial: qcom-geni: fix opp vote on shutdown The operating-performance-point vote needs to be dropped when shutting down the port to avoid wasting power by keeping resources like power domains in an unnecessarily high performance state (e.g. when a UART connected Bluetooth controller is not in use). Fixes: a5819b548af0 ("tty: serial: qcom_geni_serial: Use OPP API to set clk/perf state") Cc: stable@vger.kernel.org # 5.9 Cc: Rajendra Nayak Cc: Matthias Kaehlcke Signed-off-by: Johan Hovold Acked-by: Konrad Dybcio Link: https://lore.kernel.org/r/20230714130214.14552-2-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index a1c8dcd781da..295dfba43904 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -125,6 +125,7 @@ struct qcom_geni_serial_port { dma_addr_t rx_dma_addr; bool setup; unsigned int baud; + unsigned long clk_rate; void *rx_buf; u32 loopback; bool brk; @@ -1248,6 +1249,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, baud * sampling_rate, clk_rate, clk_div); uport->uartclk = clk_rate; + port->clk_rate = clk_rate; dev_pm_opp_set_rate(uport->dev, clk_rate); ser_clk_cfg = SER_CLK_EN; ser_clk_cfg |= clk_div << CLK_DIV_SHFT; @@ -1512,10 +1514,13 @@ static void qcom_geni_serial_pm(struct uart_port *uport, if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) { geni_icc_enable(&port->se); + if (port->clk_rate) + dev_pm_opp_set_rate(uport->dev, port->clk_rate); geni_se_resources_on(&port->se); } else if (new_state == UART_PM_STATE_OFF && old_state == UART_PM_STATE_ON) { geni_se_resources_off(&port->se); + dev_pm_opp_set_rate(uport->dev, 0); geni_icc_disable(&port->se); } } -- cgit v1.2.3 From 18536cc8fab81f7bc010f782e06d34a1546d0648 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 14 Jul 2023 15:02:14 +0200 Subject: serial: qcom-geni: clean up clock-rate debug printk Make the clock-rate debug printk more readable by using an equal sign instead of a dash as separator between names and values and adding some spaces: qcom_geni_serial 988000.serial: desired_rate = 1843200, clk_rate = 7372800, clk_div = 4 Signed-off-by: Johan Hovold Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20230714130214.14552-3-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 295dfba43904..f96fc8a8e67f 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1245,7 +1245,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, goto out_restart_rx; } - dev_dbg(port->se.dev, "desired_rate-%u, clk_rate-%lu, clk_div-%u\n", + dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n", baud * sampling_rate, clk_rate, clk_div); uport->uartclk = clk_rate; -- cgit v1.2.3 From 7449c16d3760ec749d4a3892baeb921edb227ad9 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:39 +0800 Subject: serial: ar933x: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-1-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ar933x_uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 4c3d04c6826a..924c1a89347c 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -749,8 +749,7 @@ static int ar933x_uart_probe(struct platform_device *pdev) port = &up->port; - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - port->membase = devm_ioremap_resource(&pdev->dev, mem_res); + port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res); if (IS_ERR(port->membase)) return PTR_ERR(port->membase); -- cgit v1.2.3 From b03a4ecb407ec2b1dff2ee584d0e769c1e706d64 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:40 +0800 Subject: serial: bcm63xx-uart: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-2-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 55e82d0bf92d..0dd8cceb837c 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -832,14 +832,10 @@ static int bcm_uart_probe(struct platform_device *pdev) return -EBUSY; memset(port, 0, sizeof(*port)); - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res_mem) - return -ENODEV; - - port->mapbase = res_mem->start; - port->membase = devm_ioremap_resource(&pdev->dev, res_mem); + port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res_mem); if (IS_ERR(port->membase)) return PTR_ERR(port->membase); + port->mapbase = res_mem->start; ret = platform_get_irq(pdev, 0); if (ret < 0) -- cgit v1.2.3 From 0bb60bda3157a4bf1d7c4d958cd9f46a3c72e79c Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:41 +0800 Subject: serial: clps711x: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-3-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index be8b8788d2e2..55d19937efbd 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -451,8 +451,7 @@ static int uart_clps711x_probe(struct platform_device *pdev) if (IS_ERR(uart_clk)) return PTR_ERR(uart_clk); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - s->port.membase = devm_ioremap_resource(&pdev->dev, res); + s->port.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(s->port.membase)) return PTR_ERR(s->port.membase); -- cgit v1.2.3 From 8c6d7e5fd50b451b4de1c42e8b9faad5257fa12e Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:42 +0800 Subject: serial: linflexuart: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-4-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_linflexuart.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c index f697751c2ad5..249cb380c3c6 100644 --- a/drivers/tty/serial/fsl_linflexuart.c +++ b/drivers/tty/serial/fsl_linflexuart.c @@ -827,14 +827,10 @@ static int linflex_probe(struct platform_device *pdev) sport->line = ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - sport->mapbase = res->start; - sport->membase = devm_ioremap_resource(&pdev->dev, res); + sport->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(sport->membase)) return PTR_ERR(sport->membase); + sport->mapbase = res->start; sport->dev = &pdev->dev; sport->type = PORT_LINFLEXUART; -- cgit v1.2.3 From f9061d3b7899e946f0db6ef7b727c40c01cfbd45 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:43 +0800 Subject: serial: tegra: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-5-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial-tegra.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index f7f0841d60c9..0b597b282fce 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -1577,16 +1577,11 @@ static int tegra_uart_probe(struct platform_device *pdev) tup->cdata = cdata; platform_set_drvdata(pdev, tup); - resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!resource) { - dev_err(&pdev->dev, "No IO memory resource\n"); - return -ENODEV; - } - u->mapbase = resource->start; - u->membase = devm_ioremap_resource(&pdev->dev, resource); + u->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &resource); if (IS_ERR(u->membase)) return PTR_ERR(u->membase); + u->mapbase = resource->start; tup->uart_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(tup->uart_clk)) -- cgit v1.2.3 From fcf0be13e8d9b4fcf815d42479c513c2d0deb1a4 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:44 +0800 Subject: serial: omap: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-6-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 2c11870fa894..3dc14dcb01ca 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1571,8 +1571,7 @@ static int serial_omap_probe(struct platform_device *pdev) if (!up) return -ENOMEM; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, mem); + base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); if (IS_ERR(base)) return PTR_ERR(base); -- cgit v1.2.3 From 8f3c8d8152532e0065070385258404e2aa7f1f45 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:45 +0800 Subject: serial: fsl_lpuart: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-7-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 5c889c65d8ea..f6644c5989d3 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2848,8 +2848,7 @@ static int lpuart_probe(struct platform_device *pdev) if (!sport) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sport->port.membase = devm_ioremap_resource(&pdev->dev, res); + sport->port.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(sport->port.membase)) return PTR_ERR(sport->port.membase); -- cgit v1.2.3 From 0548688dfa3aeeefc28b1603fe9d004de119dd10 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:46 +0800 Subject: serial: vt8500: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-8-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/vt8500_serial.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 32433e9b3e5f..c5d5c2765119 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -611,10 +611,6 @@ static int vt8500_serial_probe(struct platform_device *pdev) if (!flags) return -EINVAL; - mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mmres) - return -ENODEV; - irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; @@ -647,7 +643,7 @@ static int vt8500_serial_probe(struct platform_device *pdev) if (!vt8500_port) return -ENOMEM; - vt8500_port->uart.membase = devm_ioremap_resource(&pdev->dev, mmres); + vt8500_port->uart.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &mmres); if (IS_ERR(vt8500_port->uart.membase)) return PTR_ERR(vt8500_port->uart.membase); -- cgit v1.2.3 From 6b4cda0248360dd6315d066cea0595f3c1b62f9d Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:47 +0800 Subject: serial: mps2-uart: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Acked-by: Sudeep Holla Link: https://lore.kernel.org/r/20230712062853.11007-9-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mps2-uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/mps2-uart.c b/drivers/tty/serial/mps2-uart.c index 5da88cbeec73..ea5a7911cb15 100644 --- a/drivers/tty/serial/mps2-uart.c +++ b/drivers/tty/serial/mps2-uart.c @@ -538,8 +538,7 @@ static int mps2_init_port(struct platform_device *pdev, struct resource *res; int ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mps_port->port.membase = devm_ioremap_resource(&pdev->dev, res); + mps_port->port.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(mps_port->port.membase)) return PTR_ERR(mps_port->port.membase); -- cgit v1.2.3 From f60129c4e79543e7340515a02135d4fb04782d56 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:48 +0800 Subject: serial: sprd: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-10-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sprd_serial.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 8f6fd1cd91d7..792d016c21a7 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -1180,8 +1180,7 @@ static int sprd_probe(struct platform_device *pdev) if (ret) return ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - up->membase = devm_ioremap_resource(&pdev->dev, res); + up->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(up->membase)) return PTR_ERR(up->membase); -- cgit v1.2.3 From 0851efaf334e78e46a7000860659d7c8f5710820 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:49 +0800 Subject: serial: sccnxp: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-11-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sccnxp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index 31ee46eba580..2be2c1098025 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -879,14 +879,14 @@ MODULE_DEVICE_TABLE(platform, sccnxp_id_table); static int sccnxp_probe(struct platform_device *pdev) { - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct sccnxp_pdata *pdata = dev_get_platdata(&pdev->dev); + struct resource *res; int i, ret, uartclk; struct sccnxp_port *s; void __iomem *membase; struct clk *clk; - membase = devm_ioremap_resource(&pdev->dev, res); + membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(membase)) return PTR_ERR(membase); -- cgit v1.2.3 From ffd793eba4e75628460bcab3d3bb72ee39d7b49a Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:50 +0800 Subject: serial: mvebu-uart: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-12-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mvebu-uart.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 31f739c7a08b..ea924e9b913b 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -876,18 +876,13 @@ static int uart_num_counter; static int mvebu_uart_probe(struct platform_device *pdev) { - struct resource *reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); const struct of_device_id *match = of_match_device(mvebu_uart_of_match, &pdev->dev); struct uart_port *port; struct mvebu_uart *mvuart; + struct resource *reg; int id, irq; - if (!reg) { - dev_err(&pdev->dev, "no registers defined\n"); - return -EINVAL; - } - /* Assume that all UART ports have a DT alias or none has */ id = of_alias_get_id(pdev->dev.of_node, "serial"); if (!pdev->dev.of_node || id < 0) @@ -922,11 +917,11 @@ static int mvebu_uart_probe(struct platform_device *pdev) */ port->irq = 0; port->irqflags = 0; - port->mapbase = reg->start; - port->membase = devm_ioremap_resource(&pdev->dev, reg); + port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, ®); if (IS_ERR(port->membase)) return PTR_ERR(port->membase); + port->mapbase = reg->start; mvuart = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart), GFP_KERNEL); -- cgit v1.2.3 From b75c1da925d991acae8b2abbb2e5ea321b9bbefb Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:51 +0800 Subject: serial: sifive: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-13-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sifive.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index c00080f12cab..6d2685ca4602 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -917,12 +917,9 @@ static int sifive_serial_probe(struct platform_device *pdev) if (irq < 0) return -EPROBE_DEFER; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, mem); - if (IS_ERR(base)) { - dev_err(&pdev->dev, "could not acquire device memory\n"); + base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); + if (IS_ERR(base)) return PTR_ERR(base); - } clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) { -- cgit v1.2.3 From 57c2dab5596a2bd0cda64fcc208efdefe296788f Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:52 +0800 Subject: serial: imx: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-14-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/imx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 3ed5083a7108..13cb78340709 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -2275,8 +2275,7 @@ static int imx_uart_probe(struct platform_device *pdev) return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(base)) return PTR_ERR(base); -- cgit v1.2.3 From 9b4e18f032db160a70d73d3cdf3a0bff229686b4 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 12 Jul 2023 14:28:53 +0800 Subject: serial: st-asc: Use devm_platform_get_and_ioremap_resource() Convert platform_get_resource(), devm_ioremap_resource() to a single call to devm_platform_get_and_ioremap_resource(), as this is exactly what this function does. Signed-off-by: Yangtao Li Link: https://lore.kernel.org/r/20230712062853.11007-15-frank.li@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 387bc69bb1fe..b8954f0bba8f 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -691,8 +691,7 @@ static int asc_init_port(struct asc_port *ascport, port->irq = platform_get_irq(pdev, 0); port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_ST_ASC_CONSOLE); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - port->membase = devm_ioremap_resource(&pdev->dev, res); + port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(port->membase)) return PTR_ERR(port->membase); port->mapbase = res->start; -- cgit v1.2.3 From 5f45b336fc57cb31c81d2eb4a63008ab65840a2b Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 28 Jul 2023 16:57:23 +0800 Subject: 8250_men_mcb: fix error handling in read_uarts_available_from_reg() If ioremap() fails, it returns NULL pointer, not ERR_PTR(), fix the return value check and call release_mem_region() to release resource. Fixes: c563831ba879 ("8250_men_mcb: Make UART config auto configurable") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20230728085723.3195044-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index c3143ffddea0..5f301195575d 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -94,8 +94,11 @@ static int read_uarts_available_from_register(struct resource *mem_res, mem = ioremap(mem_res->start + MEN_Z025_REGISTER_OFFSET, MEM_UART_REGISTER_SIZE); - if (IS_ERR(mem)) + if (!mem) { + release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET, + MEM_UART_REGISTER_SIZE); return -ENOMEM; + } reg_value = MEN_READ_REGISTER(mem); -- cgit v1.2.3 From 17be181b061b4b7b72d4ffb856d94a356592bfd7 Mon Sep 17 00:00:00 2001 From: Dmitry Rokosov Date: Fri, 28 Jul 2023 10:15:22 +0300 Subject: tty: serial: meson: refactor objects definition for different devnames Macroses for name generation are not useful. They hide the real place for object declaration. Instead, use direct names such as 'meson_uart_driver_*' and 'meson_serial_console_*' for all objects. Additionally, rename 'MESON_SERIAL_CONSOLE_DEFINE()' to 'MESON_SERIAL_CONSOLE()', and 'MESON_UART_DRIVER_DEFINE()' to 'MESON_UART_DRIVER()' to simplify the code. Signed-off-by: Dmitry Rokosov Suggested-by: Neil Armstrong Link: https://lore.kernel.org/r/20230728071522.17503-1-ddrokosov@sberdevices.ru Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 84cf10b0ca5c..790d910dafa5 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -76,13 +76,8 @@ #define AML_UART_POLL_USEC 5 #define AML_UART_TIMEOUT_USEC 10000 -#define MESON_UART_DRIVER(_devname) meson_uart_driver_##_devname - -#define MESON_UART_DRIVER_DECLARE(_devname) \ - static struct uart_driver MESON_UART_DRIVER(_devname) - -MESON_UART_DRIVER_DECLARE(ttyAML); -MESON_UART_DRIVER_DECLARE(ttyS); +static struct uart_driver meson_uart_driver_ttyAML; +static struct uart_driver meson_uart_driver_ttyS; static struct uart_port *meson_ports[AML_UART_PORT_NUM]; @@ -617,21 +612,19 @@ static int meson_serial_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -#define MESON_SERIAL_CONSOLE(_devname) meson_serial_console_##_devname - -#define MESON_SERIAL_CONSOLE_DEFINE(_devname) \ - static struct console MESON_SERIAL_CONSOLE(_devname) = { \ +#define MESON_SERIAL_CONSOLE(_devname) \ + static struct console meson_serial_console_##_devname = { \ .name = __stringify(_devname), \ .write = meson_serial_console_write, \ .device = uart_console_device, \ .setup = meson_serial_console_setup, \ .flags = CON_PRINTBUFFER, \ .index = -1, \ - .data = &MESON_UART_DRIVER(_devname), \ + .data = &meson_uart_driver_##_devname, \ } -MESON_SERIAL_CONSOLE_DEFINE(ttyAML); -MESON_SERIAL_CONSOLE_DEFINE(ttyS); +MESON_SERIAL_CONSOLE(ttyAML); +MESON_SERIAL_CONSOLE(ttyS); static void meson_serial_early_console_write(struct console *co, const char *s, @@ -656,13 +649,13 @@ meson_serial_early_console_setup(struct earlycon_device *device, const char *opt OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", meson_serial_early_console_setup); -#define MESON_SERIAL_CONSOLE_PTR(_devname) (&MESON_SERIAL_CONSOLE(_devname)) +#define MESON_SERIAL_CONSOLE_PTR(_devname) (&meson_serial_console_##_devname) #else -#define MESON_SERIAL_CONSOLE_PTR(_devname) (NULL) +#define MESON_SERIAL_CONSOLE_PTR(_devname) (NULL) #endif -#define MESON_UART_DRIVER_DEFINE(_devname) \ - static struct uart_driver MESON_UART_DRIVER(_devname) = { \ +#define MESON_UART_DRIVER(_devname) \ + static struct uart_driver meson_uart_driver_##_devname = { \ .owner = THIS_MODULE, \ .driver_name = "meson_uart", \ .dev_name = __stringify(_devname), \ @@ -670,8 +663,8 @@ OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", .cons = MESON_SERIAL_CONSOLE_PTR(_devname), \ } -MESON_UART_DRIVER_DEFINE(ttyAML); -MESON_UART_DRIVER_DEFINE(ttyS); +MESON_UART_DRIVER(ttyAML); +MESON_UART_DRIVER(ttyS); static int meson_uart_probe_clocks(struct platform_device *pdev, struct uart_port *port) @@ -700,7 +693,7 @@ static int meson_uart_probe_clocks(struct platform_device *pdev, static struct uart_driver *meson_uart_current(const struct meson_uart_data *pd) { return (pd && pd->uart_driver) ? - pd->uart_driver : &MESON_UART_DRIVER(ttyAML); + pd->uart_driver : &meson_uart_driver_ttyAML; } static int meson_uart_probe(struct platform_device *pdev) @@ -819,12 +812,12 @@ static struct meson_uart_data meson_g12a_uart_data = { }; static struct meson_uart_data meson_a1_uart_data = { - .uart_driver = &MESON_UART_DRIVER(ttyS), + .uart_driver = &meson_uart_driver_ttyS, .has_xtal_div2 = false, }; static struct meson_uart_data meson_s4_uart_data = { - .uart_driver = &MESON_UART_DRIVER(ttyS), + .uart_driver = &meson_uart_driver_ttyS, .has_xtal_div2 = true, }; -- cgit v1.2.3 From 130a9571aee966ad8ba65719fe6c32db7b26db6a Mon Sep 17 00:00:00 2001 From: Yuanjun Gong Date: Mon, 17 Jul 2023 22:47:33 +0800 Subject: drivers:tty: fix return value check in asc_init_port in asc_init_port, clk_prepare_enable may fail, therefore, the return value of clk_prepare_enable should be checked. Signed-off-by: Yuanjun Gong Link: https://lore.kernel.org/r/20230717144733.24194-1-ruc_gongyuanjun@163.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index b8954f0bba8f..92b9f6894006 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -703,7 +703,9 @@ static int asc_init_port(struct asc_port *ascport, if (WARN_ON(IS_ERR(ascport->clk))) return -EINVAL; /* ensure that clk rate is correct by enabling the clk */ - clk_prepare_enable(ascport->clk); + ret = clk_prepare_enable(ascport->clk); + if (ret) + return ret; ascport->port.uartclk = clk_get_rate(ascport->clk); WARN_ON(ascport->port.uartclk == 0); clk_disable_unprepare(ascport->clk); -- cgit v1.2.3 From 77a82cebf0eb023203b4cb2235cab75afc77cccf Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Mon, 24 Jul 2023 11:47:27 +0800 Subject: serial: sc16is7xx: Put IOControl register into regmap_volatile According to the IOControl register bits description in the page 31 of the product datasheet, we know the bit 3 of IOControl register is softreset, this bit will self-clearing once the reset finish. In the probe, the softreset bit is set, and when we read this register from debugfs/regmap interface, we found the softreset bit is still setting, this confused us for a while. Finally we found this register is cached, to read the real value from register, we could put it into the regmap_volatile(). Signed-off-by: Hui Wang Link: https://lore.kernel.org/r/20230724034727.17335-1-hui.wang@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index cfffc730ba34..18a48ce052c2 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -488,6 +488,7 @@ static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg) case SC16IS7XX_TXLVL_REG: case SC16IS7XX_RXLVL_REG: case SC16IS7XX_IOSTATE_REG: + case SC16IS7XX_IOCONTROL_REG: return true; default: break; -- cgit v1.2.3 From f9608f1887568b728839d006024585ab02ef29e5 Mon Sep 17 00:00:00 2001 From: Chunyan Zhang Date: Tue, 25 Jul 2023 14:40:52 +0800 Subject: serial: sprd: Assign sprd_port after initialized to avoid wrong access The global pointer 'sprd_port' may not zero when sprd_probe returns failure, that is a risk for sprd_port to be accessed afterward, and may lead to unexpected errors. For example: There are two UART ports, UART1 is used for console and configured in kernel command line, i.e. "console="; The UART1 probe failed and the memory allocated to sprd_port[1] was released, but sprd_port[1] was not set to NULL; In UART2 probe, the same virtual address was allocated to sprd_port[2], and UART2 probe process finally will go into sprd_console_setup() to register UART1 as console since it is configured as preferred console (filled to console_cmdline[]), but the console parameters (sprd_port[1]) belong to UART2. So move the sprd_port[] assignment to where the port already initialized can avoid the above issue. Fixes: b7396a38fb28 ("tty/serial: Add Spreadtrum sc9836-uart driver support") Signed-off-by: Chunyan Zhang Link: https://lore.kernel.org/r/20230725064053.235448-1-chunyan.zhang@unisoc.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sprd_serial.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 792d016c21a7..efca715bc97e 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -1107,7 +1107,7 @@ static bool sprd_uart_is_console(struct uart_port *uport) static int sprd_clk_init(struct uart_port *uport) { struct clk *clk_uart, *clk_parent; - struct sprd_uart_port *u = sprd_port[uport->line]; + struct sprd_uart_port *u = container_of(uport, struct sprd_uart_port, port); clk_uart = devm_clk_get(uport->dev, "uart"); if (IS_ERR(clk_uart)) { @@ -1150,22 +1150,22 @@ static int sprd_probe(struct platform_device *pdev) { struct resource *res; struct uart_port *up; + struct sprd_uart_port *sport; int irq; int index; int ret; index = of_alias_get_id(pdev->dev.of_node, "serial"); - if (index < 0 || index >= ARRAY_SIZE(sprd_port)) { + if (index < 0 || index >= UART_NR_MAX) { dev_err(&pdev->dev, "got a wrong serial alias id %d\n", index); return -EINVAL; } - sprd_port[index] = devm_kzalloc(&pdev->dev, sizeof(*sprd_port[index]), - GFP_KERNEL); - if (!sprd_port[index]) + sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); + if (!sport) return -ENOMEM; - up = &sprd_port[index]->port; + up = &sport->port; up->dev = &pdev->dev; up->line = index; up->type = PORT_SPRD; @@ -1195,7 +1195,7 @@ static int sprd_probe(struct platform_device *pdev) * Allocate one dma buffer to prepare for receive transfer, in case * memory allocation failure at runtime. */ - ret = sprd_rx_alloc_buf(sprd_port[index]); + ret = sprd_rx_alloc_buf(sport); if (ret) return ret; @@ -1206,14 +1206,23 @@ static int sprd_probe(struct platform_device *pdev) return ret; } } + sprd_ports_num++; + sprd_port[index] = sport; ret = uart_add_one_port(&sprd_uart_driver, up); if (ret) - sprd_remove(pdev); + goto clean_port; platform_set_drvdata(pdev, up); + return 0; + +clean_port: + sprd_port[index] = NULL; + if (--sprd_ports_num == 0) + uart_unregister_driver(&sprd_uart_driver); + sprd_rx_free_buf(sport); return ret; } -- cgit v1.2.3 From cd119fdc3ee1450fbf7f78862b5de44c42b6e47f Mon Sep 17 00:00:00 2001 From: Chunyan Zhang Date: Tue, 25 Jul 2023 14:40:53 +0800 Subject: serial: sprd: Fix DMA buffer leak issue Release DMA buffer when _probe() returns failure to avoid memory leak. Fixes: f4487db58eb7 ("serial: sprd: Add DMA mode support") Signed-off-by: Chunyan Zhang Reviewed-by: Baolin Wang Link: https://lore.kernel.org/r/20230725064053.235448-2-chunyan.zhang@unisoc.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sprd_serial.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index efca715bc97e..f328fa57231f 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -364,7 +364,7 @@ static void sprd_rx_free_buf(struct sprd_uart_port *sp) if (sp->rx_dma.virt) dma_free_coherent(sp->port.dev, SPRD_UART_RX_SIZE, sp->rx_dma.virt, sp->rx_dma.phys_addr); - + sp->rx_dma.virt = NULL; } static int sprd_rx_dma_config(struct uart_port *port, u32 burst) @@ -1203,7 +1203,7 @@ static int sprd_probe(struct platform_device *pdev) ret = uart_register_driver(&sprd_uart_driver); if (ret < 0) { pr_err("Failed to register SPRD-UART driver\n"); - return ret; + goto free_rx_buf; } } @@ -1222,6 +1222,7 @@ clean_port: sprd_port[index] = NULL; if (--sprd_ports_num == 0) uart_unregister_driver(&sprd_uart_driver); +free_rx_buf: sprd_rx_free_buf(sport); return ret; } -- cgit v1.2.3 From e6015e3ded636e63b5f166241a3487469d0f73a8 Mon Sep 17 00:00:00 2001 From: Jiaqing Zhao Date: Mon, 24 Jul 2023 08:39:30 +0000 Subject: can: ems_pci: remove PCI_SUBVENDOR_ID_ASIX definition PCI_SUBVENDOR_ID_ASIX is defined as 0xa000, which is not the vendor id assigned to ASIX by PCI-SIG. Remove it to avoid possible confusion and conflict. Signed-off-by: Jiaqing Zhao Reviewed-by: Andy Shevchenko Acked-by: Marc Kleine-Budde Link: https://lore.kernel.org/r/20230724083933.3173513-2-jiaqing.zhao@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/sja1000/ems_pci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c index c56e27223e5f..3e18c63a982c 100644 --- a/drivers/net/can/sja1000/ems_pci.c +++ b/drivers/net/can/sja1000/ems_pci.c @@ -111,7 +111,6 @@ struct ems_pci_card { #ifndef PCI_VENDOR_ID_ASIX #define PCI_VENDOR_ID_ASIX 0x125b #define PCI_DEVICE_ID_ASIX_9110 0x9110 -#define PCI_SUBVENDOR_ID_ASIX 0xa000 #endif #define PCI_SUBDEVICE_ID_EMS 0x4010 @@ -123,7 +122,7 @@ static const struct pci_device_id ems_pci_tbl[] = { /* CPC-104P v2 */ {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_PLX, 0x4002}, /* CPC-PCIe v3 */ - {PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_9110, PCI_SUBVENDOR_ID_ASIX, PCI_SUBDEVICE_ID_EMS}, + {PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_9110, 0xa000, PCI_SUBDEVICE_ID_EMS}, {0,} }; MODULE_DEVICE_TABLE(pci, ems_pci_tbl); -- cgit v1.2.3 From 3029ad91335353a70feb42acd24d580d70ab258b Mon Sep 17 00:00:00 2001 From: Jiaqing Zhao Date: Mon, 24 Jul 2023 08:39:31 +0000 Subject: can: ems_pci: move ASIX AX99100 ids to pci_ids.h Move PCI Vendor and Device ID of ASIX AX99100 PCIe to Multi I/O Controller to pci_ids.h for its serial and parallel port driver support in subsequent patches. Signed-off-by: Jiaqing Zhao Reviewed-by: Andy Shevchenko Acked-by: Bjorn Helgaas Acked-by: Marc Kleine-Budde Link: https://lore.kernel.org/r/20230724083933.3173513-3-jiaqing.zhao@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/sja1000/ems_pci.c | 6 +----- include/linux/pci_ids.h | 4 ++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c index 3e18c63a982c..1aaedaf866f1 100644 --- a/drivers/net/can/sja1000/ems_pci.c +++ b/drivers/net/can/sja1000/ems_pci.c @@ -108,10 +108,6 @@ struct ems_pci_card { #define EMS_PCI_BASE_SIZE 4096 /* size of controller area */ -#ifndef PCI_VENDOR_ID_ASIX -#define PCI_VENDOR_ID_ASIX 0x125b -#define PCI_DEVICE_ID_ASIX_9110 0x9110 -#endif #define PCI_SUBDEVICE_ID_EMS 0x4010 static const struct pci_device_id ems_pci_tbl[] = { @@ -122,7 +118,7 @@ static const struct pci_device_id ems_pci_tbl[] = { /* CPC-104P v2 */ {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_PLX, 0x4002}, /* CPC-PCIe v3 */ - {PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_9110, 0xa000, PCI_SUBDEVICE_ID_EMS}, + {PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100_LB, 0xa000, PCI_SUBDEVICE_ID_EMS}, {0,} }; MODULE_DEVICE_TABLE(pci, ems_pci_tbl); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 2dc75df1437f..16608ce4fd0f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1760,6 +1760,10 @@ #define PCI_SUBDEVICE_ID_AT_2700FX 0x2701 #define PCI_SUBDEVICE_ID_AT_2701FX 0x2703 +#define PCI_VENDOR_ID_ASIX 0x125b +#define PCI_DEVICE_ID_ASIX_AX99100 0x9100 +#define PCI_DEVICE_ID_ASIX_AX99100_LB 0x9110 + #define PCI_VENDOR_ID_ESS 0x125d #define PCI_DEVICE_ID_ESS_ESS1968 0x1968 #define PCI_DEVICE_ID_ESS_ESS1978 0x1978 -- cgit v1.2.3 From 0b32216557ce3b2a468d1282d99b428bf72ff532 Mon Sep 17 00:00:00 2001 From: Jiaqing Zhao Date: Mon, 24 Jul 2023 08:39:32 +0000 Subject: serial: 8250_pci: add support for ASIX AX99100 Each of the 4 PCI functions on ASIX AX99100 PCIe to Multi I/O Controller can be configured as a single-port serial port controller. The subvendor id is 0x1000 when configured as serial port and MSI interrupts are supported. Signed-off-by: Jiaqing Zhao Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230724083933.3173513-4-jiaqing.zhao@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index d2d547b5da95..62a9bd30b4db 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -67,6 +67,8 @@ static const struct pci_device_id pci_use_msi[] = { 0xA000, 0x1000) }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922, 0xA000, 0x1000) }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100, + 0xA000, 0x1000) }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_HP_3PAR, PCI_DEVICE_ID_HPE_PCI_SERIAL, PCI_ANY_ID, PCI_ANY_ID) }, { } @@ -5557,6 +5559,14 @@ static const struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, 0xA000, 0x3004, 0, 0, pbn_b0_bt_4_115200 }, + + /* + * ASIX AX99100 PCIe to Multi I/O Controller + */ + { PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100, + 0xA000, 0x1000, + 0, 0, pbn_b0_1_115200 }, + /* Intel CE4100 */ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART, PCI_ANY_ID, PCI_ANY_ID, 0, 0, -- cgit v1.2.3 From 16aae4c64600a6319a6f10dbff833fa198bf9599 Mon Sep 17 00:00:00 2001 From: Jiaqing Zhao Date: Mon, 24 Jul 2023 08:39:33 +0000 Subject: parport_pc: add support for ASIX AX99100 The PCI function 2 on ASIX AX99100 PCIe to Multi I/O Controller can be configured as a single-port parallel port controller. The subvendor id is 0x2000 when configured as parallel port. It supports IEEE-1284 EPP / ECP with its ECR on BAR1. Signed-off-by: Jiaqing Zhao Reviewed-by: Andy Shevchenko Acked-by: Sudip Mukherjee Link: https://lore.kernel.org/r/20230724083933.3173513-5-jiaqing.zhao@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/parport/parport_pc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 3bacbaf16f42..1f236aaf7867 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -2655,6 +2655,7 @@ enum parport_pc_pci_cards { netmos_9815, netmos_9901, netmos_9865, + asix_ax99100, quatech_sppxp100, wch_ch382l, }; @@ -2733,6 +2734,7 @@ static struct parport_pc_pci { /* netmos_9815 */ { 2, { { 0, 1 }, { 2, 3 }, } }, /* netmos_9901 */ { 1, { { 0, -1 }, } }, /* netmos_9865 */ { 1, { { 0, -1 }, } }, + /* asix_ax99100 */ { 1, { { 0, 1 }, } }, /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, /* wch_ch382l */ { 1, { { 2, -1 }, } }, }; @@ -2823,6 +2825,9 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { 0xA000, 0x1000, 0, 0, netmos_9865 }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, 0xA000, 0x2000, 0, 0, netmos_9865 }, + /* ASIX AX99100 PCIe to Multi I/O Controller */ + { PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100, + 0xA000, 0x2000, 0, 0, asix_ax99100 }, /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, -- cgit v1.2.3 From 602c802114a10cb03415fbed0163ca9ff97fc5d4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:35 +0200 Subject: serial: move WARN_ON() in uart_write() to the condition uart code currently does the following in uart_write() and uart_flush_buffer(): if (cond) { WARN_ON(1); return; } It can be rewritten to more obvious and more readable: if (WARN_ON(cond)) return; Do so. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230731080244.2698-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 306ea1a560e6..e31c9b6bd8ab 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -593,10 +593,8 @@ static int uart_write(struct tty_struct *tty, * This means you called this function _after_ the port was * closed. No cookie for you. */ - if (!state) { - WARN_ON(1); + if (WARN_ON(!state)) return -EL3HLT; - } port = uart_port_lock(state, flags); circ = &state->xmit; @@ -659,10 +657,8 @@ static void uart_flush_buffer(struct tty_struct *tty) * This means you called this function _after_ the port was * closed. No cookie for you. */ - if (!state) { - WARN_ON(1); + if (WARN_ON(!state)) return; - } pr_debug("uart_flush_buffer(%d) called\n", tty->index); -- cgit v1.2.3 From 659705d0a6992892bf3713bccf91ba43111aa71e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:36 +0200 Subject: Bluetooth: rfcomm: remove casts from tty->driver_data tty->driver_data is 'void *', so there is no need to cast from that. Therefore remove the casts and assign the pointer directly. Signed-off-by: Jiri Slaby (SUSE) Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: linux-bluetooth@vger.kernel.org Link: https://lore.kernel.org/r/20230731080244.2698-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/rfcomm/tty.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 5697df9d4394..d73eec146529 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -771,7 +771,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->port.count); @@ -781,7 +781,7 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; struct rfcomm_dlc *dlc = dev->dlc; struct sk_buff *skb; int sent = 0, size; @@ -810,7 +810,7 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in static unsigned int rfcomm_tty_write_room(struct tty_struct *tty) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; int room = 0; if (dev && dev->dlc) @@ -864,7 +864,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, u8 baud, data_bits, stop_bits, parity, x_on, x_off; u16 changes = 0; - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; BT_DBG("tty %p termios %p", tty, old); @@ -996,7 +996,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, static void rfcomm_tty_throttle(struct tty_struct *tty) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; BT_DBG("tty %p dev %p", tty, dev); @@ -1005,7 +1005,7 @@ static void rfcomm_tty_throttle(struct tty_struct *tty) static void rfcomm_tty_unthrottle(struct tty_struct *tty) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; BT_DBG("tty %p dev %p", tty, dev); @@ -1014,7 +1014,7 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty) static unsigned int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; BT_DBG("tty %p dev %p", tty, dev); @@ -1029,7 +1029,7 @@ static unsigned int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) static void rfcomm_tty_flush_buffer(struct tty_struct *tty) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; BT_DBG("tty %p dev %p", tty, dev); @@ -1052,7 +1052,7 @@ static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) static void rfcomm_tty_hangup(struct tty_struct *tty) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; BT_DBG("tty %p dev %p", tty, dev); @@ -1061,7 +1061,7 @@ static void rfcomm_tty_hangup(struct tty_struct *tty) static int rfcomm_tty_tiocmget(struct tty_struct *tty) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; BT_DBG("tty %p dev %p", tty, dev); @@ -1070,7 +1070,7 @@ static int rfcomm_tty_tiocmget(struct tty_struct *tty) static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { - struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + struct rfcomm_dev *dev = tty->driver_data; struct rfcomm_dlc *dlc = dev->dlc; u8 v24_sig; -- cgit v1.2.3 From d3352ab0a9701a6d4c88b814815d7320c339f4a8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:37 +0200 Subject: tty: hvsi: remove an extra variable from hvsi_write() 'source' is the same as 'buf'. Rename the parameter ('buf') to 'source' and drop the local variable. Likely, the two were introduced to have a different type. But 'char' and 'unsigned char' are the same in the kernel for a long time. Signed-off-by: Jiri Slaby (SUSE) Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230731080244.2698-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index a200d01eceed..c1b8a4fd8b1e 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -905,10 +905,9 @@ static unsigned int hvsi_chars_in_buffer(struct tty_struct *tty) } static int hvsi_write(struct tty_struct *tty, - const unsigned char *buf, int count) + const unsigned char *source, int count) { struct hvsi_struct *hp = tty->driver_data; - const char *source = buf; unsigned long flags; int total = 0; int origcount = count; -- cgit v1.2.3 From ca1a8d2f50bb32ba4f43fff84590db21c8a87825 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:38 +0200 Subject: input: serport: remove casts from tty->disc_data tty->disc_data is 'void *', so there is no need to cast from that. Therefore remove the casts and assign the pointer directly. Signed-off-by: Jiri Slaby (SUSE) Cc: Dmitry Torokhov Cc: linux-input@vger.kernel.org Link: https://lore.kernel.org/r/20230731080244.2698-5-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/input/serio/serport.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 7f7ef0e3a749..a5d8953f5904 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -103,7 +103,7 @@ static int serport_ldisc_open(struct tty_struct *tty) static void serport_ldisc_close(struct tty_struct *tty) { - struct serport *serport = (struct serport *) tty->disc_data; + struct serport *serport = tty->disc_data; kfree(serport); } @@ -117,7 +117,7 @@ static void serport_ldisc_close(struct tty_struct *tty) static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, const char *fp, int count) { - struct serport *serport = (struct serport*) tty->disc_data; + struct serport *serport = tty->disc_data; unsigned long flags; unsigned int ch_flags = 0; int i; @@ -161,7 +161,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, unsigned char *kbuf, size_t nr, void **cookie, unsigned long offset) { - struct serport *serport = (struct serport*) tty->disc_data; + struct serport *serport = tty->disc_data; struct serio *serio; if (test_and_set_bit(SERPORT_BUSY, &serport->flags)) @@ -245,7 +245,7 @@ static int serport_ldisc_compat_ioctl(struct tty_struct *tty, static void serport_ldisc_hangup(struct tty_struct *tty) { - struct serport *serport = (struct serport *) tty->disc_data; + struct serport *serport = tty->disc_data; unsigned long flags; spin_lock_irqsave(&serport->lock, flags); @@ -257,7 +257,7 @@ static void serport_ldisc_hangup(struct tty_struct *tty) static void serport_ldisc_write_wakeup(struct tty_struct * tty) { - struct serport *serport = (struct serport *) tty->disc_data; + struct serport *serport = tty->disc_data; unsigned long flags; spin_lock_irqsave(&serport->lock, flags); -- cgit v1.2.3 From 0e4a23ce7cc29b8e661446b7c622f220bc1db5ca Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:39 +0200 Subject: can: slcan: remove casts from tty->disc_data tty->disc_data is 'void *', so there is no need to cast from that. Therefore remove the casts and assign the pointer directly. Signed-off-by: Jiri Slaby (SUSE) Cc: Dario Binacchi Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: linux-can@vger.kernel.org Cc: netdev@vger.kernel.org Acked-by: Marc Kleine-Budde Link: https://lore.kernel.org/r/20230731080244.2698-6-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/slcan/slcan-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c index f4db77007c13..371af9d17b14 100644 --- a/drivers/net/can/slcan/slcan-core.c +++ b/drivers/net/can/slcan/slcan-core.c @@ -583,7 +583,7 @@ static void slcan_transmit(struct work_struct *work) */ static void slcan_write_wakeup(struct tty_struct *tty) { - struct slcan *sl = (struct slcan *)tty->disc_data; + struct slcan *sl = tty->disc_data; schedule_work(&sl->tx_work); } @@ -778,7 +778,7 @@ static void slcan_receive_buf(struct tty_struct *tty, const unsigned char *cp, const char *fp, int count) { - struct slcan *sl = (struct slcan *)tty->disc_data; + struct slcan *sl = tty->disc_data; if (!netif_running(sl->dev)) return; @@ -862,7 +862,7 @@ static int slcan_open(struct tty_struct *tty) */ static void slcan_close(struct tty_struct *tty) { - struct slcan *sl = (struct slcan *)tty->disc_data; + struct slcan *sl = tty->disc_data; unregister_candev(sl->dev); @@ -886,7 +886,7 @@ static void slcan_close(struct tty_struct *tty) static int slcan_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct slcan *sl = (struct slcan *)tty->disc_data; + struct slcan *sl = tty->disc_data; unsigned int tmp; switch (cmd) { -- cgit v1.2.3 From 3e6e212f614c3af6ac324b8042ea2c99a2818ba8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:40 +0200 Subject: serial: altera_jtaguart: switch status to u32 'status' is assigned a result from readl(). There is no need for the variable to be 'unsigned long'. readl() returns 32bit values. Provided, this is a Nios II driver (32-bit), there is no change in semantics. This only makes the type explicit. Signed-off-by: Jiri Slaby (SUSE) Cc: Tobias Klauser Link: https://lore.kernel.org/r/20230731080244.2698-7-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 6203ca1de769..5fab4c978891 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -110,7 +110,7 @@ static void altera_jtaguart_set_termios(struct uart_port *port, static void altera_jtaguart_rx_chars(struct uart_port *port) { - unsigned long status; + u32 status; u8 ch; while ((status = readl(port->membase + ALTERA_JTAGUART_DATA_REG)) & -- cgit v1.2.3 From 6dc6657d890f5e4b45377e2bba8a437cafd0e750 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:41 +0200 Subject: speakup: switch to unsigned iterator in spk_ttyio_receive_buf2() Now, that spk_ttyio_receive_buf2() receives an unsigned count, the iterator can/should be unsigned too. Switch to that to be explicit. Signed-off-by: Jiri Slaby (SUSE) Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Cc: Samuel Thibault Cc: speakup@linux-speakup.org Link: https://lore.kernel.org/r/20230731080244.2698-8-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 07373b3debd1..5d4bafe118ec 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -79,7 +79,7 @@ static int spk_ttyio_receive_buf2(struct tty_struct *tty, struct spk_synth *synth = ldisc_data->synth; if (synth->read_buff_add) { - int i; + unsigned int i; for (i = 0; i < count; i++) synth->read_buff_add(cp[i]); -- cgit v1.2.3 From 99037697410f4df41558fc4227a9141dc1e24f59 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:42 +0200 Subject: misc: ti-st: remove forward declarations and make st_int_recv() static st_kim_recv() is already declared in linux/ti_wilink_st.h. Given that is already included in st_core.c, drop the re-declaration from there. st_int_recv() is used only in st_core.c and the forward declaration is not needed. So drop the declaration and make the function static. Signed-off-by: Jiri Slaby (SUSE) Cc: Arnd Bergmann Link: https://lore.kernel.org/r/20230731080244.2698-9-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 01d2257deea4..389901276ce3 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -16,8 +16,6 @@ #include -extern void st_kim_recv(void *, const unsigned char *, long); -void st_int_recv(void *, const unsigned char *, long); /* * function pointer pointing to either, * st_kim_recv during registration to receive fw download responses @@ -225,7 +223,7 @@ static inline void st_wakeup_ack(struct st_data_s *st_gdata, * HCI-Events, ACL, SCO, 4 types of HCI-LL PM packets * CH-8 packets from FM, CH-9 packets from GPS cores. */ -void st_int_recv(void *disc_data, +static void st_int_recv(void *disc_data, const unsigned char *data, long count) { char *ptr; -- cgit v1.2.3 From a60b3017601ef7f338ac44b942e917362f222b1c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:43 +0200 Subject: misc: ti-st: remove ptr from recv functions ptr is the same as data, so use ptr directly as a parameter and drop the useless local variable. Likely, the two were introduced to have a different type. But 'char' and 'unsigned char' are the same in the kernel for a long time. Signed-off-by: Jiri Slaby (SUSE) Cc: Arnd Bergmann Link: https://lore.kernel.org/r/20230731080244.2698-10-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 4 +--- drivers/misc/ti-st/st_kim.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 389901276ce3..e2add50b191c 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -224,9 +224,8 @@ static inline void st_wakeup_ack(struct st_data_s *st_gdata, * CH-8 packets from FM, CH-9 packets from GPS cores. */ static void st_int_recv(void *disc_data, - const unsigned char *data, long count) + const unsigned char *ptr, long count) { - char *ptr; struct st_proto_s *proto; unsigned short payload_len = 0; int len = 0; @@ -235,7 +234,6 @@ static void st_int_recv(void *disc_data, struct st_data_s *st_gdata = (struct st_data_s *)disc_data; unsigned long flags; - ptr = (char *)data; /* tty_receive sent null ? */ if (unlikely(ptr == NULL) || (st_gdata == NULL)) { pr_err(" received null from TTY "); diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index f2f6cab97c08..8c801897ffa2 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -128,15 +128,13 @@ static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len) * tty_receive and hence the logic */ static void kim_int_recv(struct kim_data_s *kim_gdata, - const unsigned char *data, long count) + const unsigned char *ptr, long count) { - const unsigned char *ptr; int len = 0; unsigned char *plen; pr_debug("%s", __func__); /* Decode received bytes here */ - ptr = data; if (unlikely(ptr == NULL)) { pr_err(" received null from TTY "); return; -- cgit v1.2.3 From 9b5752d1a882c96c0319aebe55bbfe9ad0c9aa30 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:02:44 +0200 Subject: misc: ti-st: don't check for tty data == NULL tty data passed to tty_ldisc_ops::receive_buf() are never NULL. Remove this check. Signed-off-by: Jiri Slaby (SUSE) Cc: Arnd Bergmann Link: https://lore.kernel.org/r/20230731080244.2698-11-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 3 +-- drivers/misc/ti-st/st_kim.c | 5 ----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index e2add50b191c..3b2145722bd7 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -234,8 +234,7 @@ static void st_int_recv(void *disc_data, struct st_data_s *st_gdata = (struct st_data_s *)disc_data; unsigned long flags; - /* tty_receive sent null ? */ - if (unlikely(ptr == NULL) || (st_gdata == NULL)) { + if (st_gdata == NULL) { pr_err(" received null from TTY "); return; } diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 8c801897ffa2..5431a89924aa 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -135,11 +135,6 @@ static void kim_int_recv(struct kim_data_s *kim_gdata, pr_debug("%s", __func__); /* Decode received bytes here */ - if (unlikely(ptr == NULL)) { - pr_err(" received null from TTY "); - return; - } - while (count) { if (kim_gdata->rx_count) { len = min_t(unsigned int, kim_gdata->rx_count, count); -- cgit v1.2.3 From fe14cbc604af78348b5790832a5455541d572704 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:59:56 +0200 Subject: tty: synclink_gt: convert CALC_REGADDR() macro to an inline It makes the code more readable and less error-prone as the result is returned and not stored in a variable newly defined inside the macro. Note that cast to 'unsigned long' and back to 'void *' was eliminated as info->reg_addr is 'char *' already (so the addition is per bytes already). This nicely cleans up the callers too. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230731090002.15680-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 16e469e581ec..00efed2c139e 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3734,47 +3734,47 @@ module_exit(slgt_exit); * register access routines */ -#define CALC_REGADDR() \ - unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ - if (addr >= 0x80) \ - reg_addr += (info->port_num) * 32; \ - else if (addr >= 0x40) \ - reg_addr += (info->port_num) * 16; +static inline void __iomem *calc_regaddr(struct slgt_info *info, + unsigned int addr) +{ + void __iomem *reg_addr = info->reg_addr + addr; + + if (addr >= 0x80) + reg_addr += info->port_num * 32; + else if (addr >= 0x40) + reg_addr += info->port_num * 16; + + return reg_addr; +} static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) { - CALC_REGADDR(); - return readb((void __iomem *)reg_addr); + return readb(calc_regaddr(info, addr)); } static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value) { - CALC_REGADDR(); - writeb(value, (void __iomem *)reg_addr); + writeb(value, calc_regaddr(info, addr)); } static __u16 rd_reg16(struct slgt_info *info, unsigned int addr) { - CALC_REGADDR(); - return readw((void __iomem *)reg_addr); + return readw(calc_regaddr(info, addr)); } static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value) { - CALC_REGADDR(); - writew(value, (void __iomem *)reg_addr); + writew(value, calc_regaddr(info, addr)); } static __u32 rd_reg32(struct slgt_info *info, unsigned int addr) { - CALC_REGADDR(); - return readl((void __iomem *)reg_addr); + return readl(calc_regaddr(info, addr)); } static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value) { - CALC_REGADDR(); - writel(value, (void __iomem *)reg_addr); + writel(value, calc_regaddr(info, addr)); } static void rdma_reset(struct slgt_info *info) -- cgit v1.2.3 From 6340b02cc75020e0c3e47e988a9c5ea806e85a48 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:59:57 +0200 Subject: tty: synclink_gt: drop global slgt_driver_name array It's used on one place, so put the containing string there directly. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230731090002.15680-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 00efed2c139e..c2ab7ecf0900 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -88,7 +88,6 @@ * module identification */ static char *driver_name = "SyncLink GT"; -static char *slgt_driver_name = "synclink_gt"; static char *tty_dev_prefix = "ttySLG"; MODULE_LICENSE("GPL"); #define MAX_DEVICES 32 @@ -3683,7 +3682,7 @@ static int __init slgt_init(void) /* Initialize the tty_driver structure */ - serial_driver->driver_name = slgt_driver_name; + serial_driver->driver_name = "synclink_gt"; serial_driver->name = tty_dev_prefix; serial_driver->major = ttymajor; serial_driver->minor_start = 64; -- cgit v1.2.3 From e33ec544baa85b447b9decbe39cdc642c1366380 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:59:58 +0200 Subject: tty: synclink_gt: define global strings as const strings And not non-const pointers to strings. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230731090002.15680-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index c2ab7ecf0900..a8716a81ac74 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -87,8 +87,8 @@ /* * module identification */ -static char *driver_name = "SyncLink GT"; -static char *tty_dev_prefix = "ttySLG"; +static const char driver_name[] = "SyncLink GT"; +static const char tty_dev_prefix[] = "ttySLG"; MODULE_LICENSE("GPL"); #define MAX_DEVICES 32 -- cgit v1.2.3 From 833c31d244597d9521e199f16d6eb169ea517733 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 10:59:59 +0200 Subject: tty: synclink_gt: drop info messages from init/exit functions It is preferred NOT to print anything from init and exit functions of a module. (If everything goes fine.) Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230731090002.15680-5-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index a8716a81ac74..4a93e0e48156 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3628,8 +3628,6 @@ static void slgt_cleanup(void) struct slgt_info *info; struct slgt_info *tmp; - printk(KERN_INFO "unload %s\n", driver_name); - if (serial_driver) { for (info=slgt_device_list ; info != NULL ; info=info->next_device) tty_unregister_device(serial_driver, info->line); @@ -3671,8 +3669,6 @@ static int __init slgt_init(void) { int rc; - printk(KERN_INFO "%s\n", driver_name); - serial_driver = tty_alloc_driver(MAX_DEVICES, TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); if (IS_ERR(serial_driver)) { @@ -3701,9 +3697,6 @@ static int __init slgt_init(void) goto error; } - printk(KERN_INFO "%s, tty major#%d\n", - driver_name, serial_driver->major); - slgt_device_count = 0; if ((rc = pci_register_driver(&pci_driver)) < 0) { printk("%s pci_register_driver error=%d\n", driver_name, rc); @@ -3711,9 +3704,6 @@ static int __init slgt_init(void) } pci_registered = true; - if (!slgt_device_list) - printk("%s no devices found\n",driver_name); - return 0; error: -- cgit v1.2.3 From 0e0a0380fd40d7230b6ca2c67810017ab03a1d0a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 11:00:00 +0200 Subject: tty: synclink_gt: use PCI_VDEVICE It makes the device entries quite a bit readable. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230731090002.15680-6-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 4a93e0e48156..381b2e22fa96 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -93,11 +93,11 @@ MODULE_LICENSE("GPL"); #define MAX_DEVICES 32 static const struct pci_device_id pci_table[] = { - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {0,}, /* terminate list */ + { PCI_VDEVICE(MICROGATE, SYNCLINK_GT_DEVICE_ID) }, + { PCI_VDEVICE(MICROGATE, SYNCLINK_GT2_DEVICE_ID) }, + { PCI_VDEVICE(MICROGATE, SYNCLINK_GT4_DEVICE_ID) }, + { PCI_VDEVICE(MICROGATE, SYNCLINK_AC_DEVICE_ID) }, + { 0 }, /* terminate list */ }; MODULE_DEVICE_TABLE(pci, pci_table); -- cgit v1.2.3 From fe61b57fc0f27a7df81a1a355defb8ddcb9731cb Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 11:00:01 +0200 Subject: tty: synclink_gt: make default_params const default_params are only read, so move them from .data to .rodata using 'const'. Signed-off-by: Jiri Slaby (SUSE) Link: https://lore.kernel.org/r/20230731090002.15680-7-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 381b2e22fa96..fe53e9c2c9b4 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -322,7 +322,7 @@ struct slgt_info { }; -static MGSL_PARAMS default_params = { +static const MGSL_PARAMS default_params = { .mode = MGSL_MODE_HDLC, .loopback = 0, .flags = HDLC_FLAG_UNDERRUN_ABORT15, -- cgit v1.2.3 From 426263d5fb400ccde5444748693dc75bda18f01e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 31 Jul 2023 11:00:02 +0200 Subject: tty: synclink_gt: mark as BROKEN After walking and trying to clean up the worst in the driver, I came across the pci_driver::remove() _empty_ implementation. That would crash the system at least during hot-unplug (or write to remove in sysfs). There are many other problems: * Initialization + deinitialization apparently comes from no-hotplug support age. It needs a rewrite. * Hairy debug macros. Drop them. * Use of self-baked lists. Replace by list. * The order of the functions should be inverted and fwd decls dropped. * Coding style from the stone age. Fix. * I assume there are many bugs, but the code is unreadable at times, so hard to judge. There is one example posted [1]. I was able to find only one user back in 2016. So mark the driver as BROKEN for some time. Either someone will notice and we can bring the driver to this century. Or we will drop it completely if noone cares. [1] https://lore.kernel.org/all/20230728123901.64225-1-dg573847474@gmail.com/ Signed-off-by: Jiri Slaby (SUSE) Cc: Chengfeng Ye Link: https://lore.kernel.org/r/20230731090002.15680-8-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 341abaed4ce2..907a7cb1d186 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -236,6 +236,7 @@ config MOXA_SMARTIO config SYNCLINK_GT tristate "SyncLink GT/AC support" depends on SERIAL_NONSTANDARD && PCI + depends on BROKEN help Support for SyncLink GT and SyncLink AC families of synchronous and asynchronous serial adapters -- cgit v1.2.3 From a35f38991c2e22c41aa9cd67bd6c55de5d9972dc Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 1 Aug 2023 08:22:36 +0200 Subject: can: can327: remove casts from tty->disc_data tty->disc_data is 'void *', so there is no need to cast from that. Therefore remove the casts and assign the pointer directly. Signed-off-by: Jiri Slaby (SUSE) Cc: Max Staudt Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Dario Binacchi Cc: linux-can@vger.kernel.org Cc: netdev@vger.kernel.org Reviewed-by: Simon Horman Reviewed-by: Max Staudt Link: https://lore.kernel.org/r/20230801062237.2687-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/can327.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c index dc7192ecb001..ee8a977acc8d 100644 --- a/drivers/net/can/can327.c +++ b/drivers/net/can/can327.c @@ -888,7 +888,7 @@ static bool can327_is_valid_rx_char(u8 c) static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, const char *fp, int count) { - struct can327 *elm = (struct can327 *)tty->disc_data; + struct can327 *elm = tty->disc_data; size_t first_new_char_idx; if (elm->uart_side_failure) @@ -990,7 +990,7 @@ static void can327_ldisc_tx_worker(struct work_struct *work) /* Called by the driver when there's room for more data. */ static void can327_ldisc_tx_wakeup(struct tty_struct *tty) { - struct can327 *elm = (struct can327 *)tty->disc_data; + struct can327 *elm = tty->disc_data; schedule_work(&elm->tx_work); } @@ -1067,7 +1067,7 @@ static int can327_ldisc_open(struct tty_struct *tty) */ static void can327_ldisc_close(struct tty_struct *tty) { - struct can327 *elm = (struct can327 *)tty->disc_data; + struct can327 *elm = tty->disc_data; /* unregister_netdev() calls .ndo_stop() so we don't have to. */ unregister_candev(elm->dev); @@ -1092,7 +1092,7 @@ static void can327_ldisc_close(struct tty_struct *tty) static int can327_ldisc_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct can327 *elm = (struct can327 *)tty->disc_data; + struct can327 *elm = tty->disc_data; unsigned int tmp; switch (cmd) { -- cgit v1.2.3 From 8a76d8b0751239bab10547dfb0fb3d2612bcc48a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 1 Aug 2023 08:22:37 +0200 Subject: net: nfc: remove casts from tty->disc_data tty->disc_data is 'void *', so there is no need to cast from that. Therefore remove the casts and assign the pointer directly. Signed-off-by: Jiri Slaby (SUSE) Cc: Max Staudt Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Krzysztof Kozlowski Cc: linux-can@vger.kernel.org Cc: netdev@vger.kernel.org Reviewed-by: Simon Horman Reviewed-by: Max Staudt Link: https://lore.kernel.org/r/20230801062237.2687-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- net/nfc/nci/uart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index cc8fa9e36159..082f94be0996 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -172,7 +172,7 @@ static int nci_uart_tty_open(struct tty_struct *tty) */ static void nci_uart_tty_close(struct tty_struct *tty) { - struct nci_uart *nu = (void *)tty->disc_data; + struct nci_uart *nu = tty->disc_data; /* Detach from the tty */ tty->disc_data = NULL; @@ -204,7 +204,7 @@ static void nci_uart_tty_close(struct tty_struct *tty) */ static void nci_uart_tty_wakeup(struct tty_struct *tty) { - struct nci_uart *nu = (void *)tty->disc_data; + struct nci_uart *nu = tty->disc_data; if (!nu) return; @@ -298,7 +298,7 @@ static int nci_uart_default_recv_buf(struct nci_uart *nu, const u8 *data, static void nci_uart_tty_receive(struct tty_struct *tty, const u8 *data, const char *flags, int count) { - struct nci_uart *nu = (void *)tty->disc_data; + struct nci_uart *nu = tty->disc_data; if (!nu || tty != nu->tty) return; @@ -325,7 +325,7 @@ static void nci_uart_tty_receive(struct tty_struct *tty, const u8 *data, static int nci_uart_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct nci_uart *nu = (void *)tty->disc_data; + struct nci_uart *nu = tty->disc_data; int err = 0; switch (cmd) { -- cgit v1.2.3 From 220965d15cef417a6d6ecfbd41c64d582522f48c Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Thu, 3 Aug 2023 11:23:53 +0800 Subject: tty: serial: Remove redundant initialization for ma35d1serial_driver There is a warning reported by coccinelle: ./drivers/tty/serial/ma35d1_serial.c:791:3-8: No need to set .owner here. The core will do it. The module_platform_driver() will set "THIS_MODULE" to driver.owner when register a driver for platform-level devices, so it is redundant initialization to set driver.owner in ma35d1serial_driver statement. Remove it to silence the warning. Signed-off-by: Li Zetao Link: https://lore.kernel.org/r/20230803032353.3045221-1-lizetao1@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ma35d1_serial.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/ma35d1_serial.c b/drivers/tty/serial/ma35d1_serial.c index 789593495a80..465b1def9e11 100644 --- a/drivers/tty/serial/ma35d1_serial.c +++ b/drivers/tty/serial/ma35d1_serial.c @@ -788,7 +788,6 @@ static struct platform_driver ma35d1serial_driver = { .resume = ma35d1serial_resume, .driver = { .name = "ma35d1-uart", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(ma35d1_serial_of_match), }, }; -- cgit v1.2.3 From f68279ca7f806c44fbbae0a631e5603ba426d9be Mon Sep 17 00:00:00 2001 From: oushixiong Date: Thu, 3 Aug 2023 14:54:09 +0800 Subject: tty: vt: Remove some repetitive initialization Members vc_col, vc_rows and vc_size_row of the struct vc_data have been initialized in visual_init(), so it is no longer needed to initialize them in vc_init() again. Signed-off-by: oushixiong Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/20230803065409.461031-1-oushixiong@kylinos.cn Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 1e8e57b45688..cf77011a8f4e 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -140,8 +140,7 @@ EXPORT_SYMBOL(vc_cons); static const struct consw *con_driver_map[MAX_NR_CONSOLES]; static int con_open(struct tty_struct *, struct file *); -static void vc_init(struct vc_data *vc, unsigned int rows, - unsigned int cols, int do_clear); +static void vc_init(struct vc_data *vc, int do_clear); static void gotoxy(struct vc_data *vc, int new_x, int new_y); static void save_cur(struct vc_data *vc); static void reset_terminal(struct vc_data *vc, int do_clear); @@ -1103,7 +1102,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ if (global_cursor_default == -1) global_cursor_default = 1; - vc_init(vc, vc->vc_rows, vc->vc_cols, 1); + vc_init(vc, 1); vcs_make_sysfs(currcons); atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); @@ -3398,16 +3397,10 @@ module_param_named(color, default_color, int, S_IRUGO | S_IWUSR); module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR); module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR); -static void vc_init(struct vc_data *vc, unsigned int rows, - unsigned int cols, int do_clear) +static void vc_init(struct vc_data *vc, int do_clear) { int j, k ; - vc->vc_cols = cols; - vc->vc_rows = rows; - vc->vc_size_row = cols << 1; - vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row; - set_origin(vc); vc->vc_pos = vc->vc_origin; reset_vc(vc); @@ -3475,8 +3468,7 @@ static int __init con_init(void) visual_init(vc, currcons, 1); /* Assuming vc->vc_{cols,rows,screenbuf_size} are sane here. */ vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); - vc_init(vc, vc->vc_rows, vc->vc_cols, - currcons || !vc->vc_sw->con_save_screen); + vc_init(vc, currcons || !vc->vc_sw->con_save_screen); } currcons = fg_console = 0; master_display_fg = vc = vc_cons[currcons].d; -- cgit v1.2.3 From 8b66eec1fd85ca9c4fd83f92e704de4fc0c583c1 Mon Sep 17 00:00:00 2001 From: Chengfeng Ye Date: Fri, 28 Jul 2023 12:39:01 +0000 Subject: tty: synclink_gt: Fix potential deadlock on &info->lock As &info->lock is acquired by slgt_interrupt() under irq context, other process context code acquiring the lock should disable irq, otherwise deadlock could happen if the irq preempt the execution while the lock is held in process context on the same CPU. Lock acquisition inside set_params32() does not disable irq, and this function is called by slgt_compat_ioctl() from process context. Possible deadlock scenario: slgt_compat_ioctl() -> set_params32() -> spin_lock(&info->lock) -> slgt_interrupt() -> spin_lock(&info->lock); (deadlock here) This flaw was found by an experimental static analysis tool I am developing for irq-related deadlock. x86_64 allmodconfig using gcc shows no new warning. The patch fixes the potential deadlock by spin_lock_irqsave() like other lock acquisition sites. Signed-off-by: Chengfeng Ye Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/20230728123901.64225-1-dg573847474@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/synclink_gt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index fe53e9c2c9b4..4c6366fe015c 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -1087,12 +1087,13 @@ static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *us static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *new_params) { struct MGSL_PARAMS32 tmp_params; + unsigned long flags; DBGINFO(("%s set_params32\n", info->device_name)); if (copy_from_user(&tmp_params, new_params, sizeof(struct MGSL_PARAMS32))) return -EFAULT; - spin_lock(&info->lock); + spin_lock_irqsave(&info->lock, flags); if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) { info->base_clock = tmp_params.clock_speed; } else { @@ -1110,7 +1111,7 @@ static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *ne info->params.stop_bits = tmp_params.stop_bits; info->params.parity = tmp_params.parity; } - spin_unlock(&info->lock); + spin_unlock_irqrestore(&info->lock, flags); program_hw(info); -- cgit v1.2.3 From 2c2d01a9f724a88be2895c5011689337da103c3b Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Thu, 3 Aug 2023 17:17:12 +0800 Subject: tty: serial: xilinx_uartps: Do not check for 0 return after calling platform_get_irq() Since commit a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 is invalid"), there is no possible for platform_get_irq() to return 0. Use the return value from platform_get_irq(). Signed-off-by: Ruan Jinjie Link: https://lore.kernel.org/r/20230803091712.596987-1-ruanjinjie@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/xilinx_uartps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 20a751663ef9..2e5e86a00a77 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1562,8 +1562,8 @@ static int cdns_uart_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq <= 0) { - rc = -ENXIO; + if (irq < 0) { + rc = irq; goto err_out_clk_disable; } -- cgit v1.2.3 From c58f2ae0ee94901da078a60961262df03eab7552 Mon Sep 17 00:00:00 2001 From: Anton Eliasson Date: Thu, 3 Aug 2023 13:26:42 +0200 Subject: tty: serial: samsung: Set missing PM ops for hibernation support At least freeze, restore and thaw need to be set in order for the driver to support system hibernation. The existing suspend/resume functions can be reused since those functions don't touch the device's power state or wakeup capability. Use the helper macros SET_SYSTEM_SLEEP_PM_OPS and SET_NOIRQ_SYSTEM_SLEEP_PM_OPS for symmetry with similar drivers. Signed-off-by: Anton Eliasson Link: https://lore.kernel.org/r/20230803-samsung_tty_pm_ops-v1-1-1ea7be72194d@axis.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung_tty.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index aa4a184f4a6c..07fb8a9dac63 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -2274,9 +2274,8 @@ static int s3c24xx_serial_resume_noirq(struct device *dev) } static const struct dev_pm_ops s3c24xx_serial_pm_ops = { - .suspend = s3c24xx_serial_suspend, - .resume = s3c24xx_serial_resume, - .resume_noirq = s3c24xx_serial_resume_noirq, + SET_SYSTEM_SLEEP_PM_OPS(s3c24xx_serial_suspend, s3c24xx_serial_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, s3c24xx_serial_resume_noirq) }; #define SERIAL_SAMSUNG_PM_OPS (&s3c24xx_serial_pm_ops) -- cgit v1.2.3 From fcb451ff66b4e07de78faefb07549b139b54b943 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Thu, 3 Aug 2023 16:47:53 +0800 Subject: 8250_men_mcb: Fix unsigned comparison with less than zero The data->line[i] is defined as unsigned int type, if(data->line[i] < 0) is invalid, so replace data->line[i] with res. ./drivers/tty/serial/8250/8250_men_mcb.c:223:6-19: WARNING: Unsigned expression compared with zero: data->line[i] < 0. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=6088 Signed-off-by: Jiapeng Chong Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230803084753.51253-1-jiapeng.chong@linux.alibaba.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index 5f301195575d..c27c52d18dfa 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -222,11 +222,13 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, + data->offset[i]; /* ok, register the port */ - data->line[i] = serial8250_register_8250_port(&uart); - if (data->line[i] < 0) { + res = serial8250_register_8250_port(&uart); + if (res < 0) { dev_err(&mdev->dev, "unable to register UART port\n"); - return data->line[i]; + return res; } + + data->line[i] = res; dev_info(&mdev->dev, "found MCB UART: ttyS%d\n", data->line[i]); } -- cgit v1.2.3 From 67c37756898a5a6b2941a13ae7260c89b54e0d88 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Mon, 31 Jul 2023 15:59:42 -0300 Subject: tty: n_gsm: require CAP_NET_ADMIN to attach N_GSM0710 ldisc Any unprivileged user can attach N_GSM0710 ldisc, but it requires CAP_NET_ADMIN to create a GSM network anyway. Require initial namespace CAP_NET_ADMIN to do that. Signed-off-by: Thadeu Lima de Souza Cascardo Link: https://lore.kernel.org/r/20230731185942.279611-1-cascardo@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 1cdefac4dd1b..c7a787f10a9c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3576,6 +3576,9 @@ static int gsmld_open(struct tty_struct *tty) { struct gsm_mux *gsm; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (tty->ops->write == NULL) return -EINVAL; -- cgit v1.2.3 From 5666280f88a7594ba0413247fd2cc18281e8e580 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Thu, 3 Aug 2023 10:05:51 -0400 Subject: serial: max310x: add comments for membase address workaround Add comments about workaround used to configure membase address. This follows suggestions made during review of a sc16is7xx driver patch to add the same workaround. Link: https://lore.kernel.org/lkml/2936e18f-44ea-faed-9fa0-2ddefe7c3194@linux.intel.com Link: https://lore.kernel.org/lkml/20230801131655.80bd8f97f018dda6155d65f6@hugovil.com/ Signed-off-by: Hugo Villeneuve Link: https://lore.kernel.org/r/20230803140551.970141-1-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 416d553b73a7..5903dd033fd0 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1369,6 +1369,11 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; s->p[i].port.iotype = UPIO_PORT; s->p[i].port.iobase = i; + /* + * Use all ones as membase to make sure uart_configure_port() in + * serial_core.c does not abort for SPI/I2C devices where the + * membase address is not applicable. + */ s->p[i].port.membase = (void __iomem *)~0; s->p[i].port.uartclk = uartclk; s->p[i].port.rs485_config = max310x_rs485_config; -- cgit v1.2.3 From 4b37932f7830cdd9dcfeb84163557705f0a7c90f Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Thu, 3 Aug 2023 13:59:31 -0400 Subject: serial: max310x: fix typos in comments cotroller -> controller. Signed-off-by: Hugo Villeneuve Link: https://lore.kernel.org/r/20230803175931.981625-1-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 5903dd033fd0..db3204d2a305 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1405,7 +1405,7 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty } #ifdef CONFIG_GPIOLIB - /* Setup GPIO cotroller */ + /* Setup GPIO controller */ s->gpio.owner = THIS_MODULE; s->gpio.parent = dev; s->gpio.label = devtype->name; -- cgit v1.2.3 From b58168698c6e462ef02c49b14989d8c9175fbfc8 Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Thu, 3 Aug 2023 22:20:53 +0800 Subject: 8250_men_mcb: Fix unsigned expression compared with zero There is a warning reported by coccinelle: ./drivers/tty/serial/8250/8250_men_mcb.c:226:6-19: WARNING: Unsigned expression compared with zero: data -> line [ i ] < 0 The array "line" of serial_8250_men_mcb_data is used to record the registered serial port. When register a port failed, it will return an error code, but the type of "line" is "unsigned int", causing the error code to reverse. Modify the type of "data -> line" to solve this problem. Fixes: 2554e6ba28a2 ("8250_men_mcb: Read num ports from register data.") Signed-off-by: Li Zetao Reviewed-by: Jiri Slaby Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230803142053.1308926-1-lizetao1@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index c27c52d18dfa..b43b7e7f8142 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -46,7 +46,7 @@ struct serial_8250_men_mcb_data { int num_ports; - unsigned int line[MAX_PORTS]; + int line[MAX_PORTS]; unsigned int offset[MAX_PORTS]; }; -- cgit v1.2.3 From 06b64930dc18c704ef2a602e596cbab676879b6f Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Fri, 4 Aug 2023 18:08:43 +0800 Subject: 8250_men_mcb: Remove redundant initialization owner in mcb_driver The module_mcb_driver() will set "THIS_MODULE" to driver.owner when register a mcb_driver driver, so it is redundant initialization to set driver.owner in mcb_driver statement. Remove it for clean code. Signed-off-by: Li Zetao Link: https://lore.kernel.org/r/20230804100843.100348-1-lizetao1@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index b43b7e7f8142..db62a3b15f19 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -258,7 +258,6 @@ MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids); static struct mcb_driver mcb_driver = { .driver = { .name = "8250_men_mcb", - .owner = THIS_MODULE, }, .probe = serial_8250_men_mcb_probe, .remove = serial_8250_men_mcb_remove, -- cgit v1.2.3 From 36ef11d311f405e55ad8e848c19b212ff71ef536 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:42 +0200 Subject: serial: cpm_uart: Avoid suspicious locking CHECK drivers/tty/serial/cpm_uart/cpm_uart_core.c drivers/tty/serial/cpm_uart/cpm_uart_core.c:1271:39: warning: context imbalance in 'cpm_uart_console_write' - unexpected unlock Allthough 'nolock' is not expected to change, sparse find the following form suspicious: if (unlikely(nolock)) { local_irq_save(flags); } else { spin_lock_irqsave(&pinfo->port.lock, flags); } cpm_uart_early_write(pinfo, s, count, true); if (unlikely(nolock)) { local_irq_restore(flags); } else { spin_unlock_irqrestore(&pinfo->port.lock, flags); } Rewrite it a more obvious form: if (unlikely(oops_in_progress)) { local_irq_save(flags); cpm_uart_early_write(pinfo, s, count, true); local_irq_restore(flags); } else { spin_lock_irqsave(&pinfo->port.lock, flags); cpm_uart_early_write(pinfo, s, count, true); spin_unlock_irqrestore(&pinfo->port.lock, flags); } Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/f7da5cdc9287960185829cfef681a7d8614efa1f.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 66afa9bea6bf..71366a4cea22 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1255,19 +1255,14 @@ static void cpm_uart_console_write(struct console *co, const char *s, { struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; unsigned long flags; - int nolock = oops_in_progress; - if (unlikely(nolock)) { + if (unlikely(oops_in_progress)) { local_irq_save(flags); - } else { - spin_lock_irqsave(&pinfo->port.lock, flags); - } - - cpm_uart_early_write(pinfo, s, count, true); - - if (unlikely(nolock)) { + cpm_uart_early_write(pinfo, s, count, true); local_irq_restore(flags); } else { + spin_lock_irqsave(&pinfo->port.lock, flags); + cpm_uart_early_write(pinfo, s, count, true); spin_unlock_irqrestore(&pinfo->port.lock, flags); } } -- cgit v1.2.3 From b5f405e53feabf4b22fb19f05ce1f104c22311df Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:43 +0200 Subject: serial: cpm_uart: Remove stale prototypes and table and macros cpm_uart_init_portdesc() smc1_lineif() smc2_lineif() scc1_lineif() scc2_lineif() scc3_lineif() scc4_lineif() Those functions were removed by commit 0b2a2e5b7747 ("cpm_uart: Remove !CONFIG_PPC_CPM_NEW_BINDING code"). Remove stale prototypes. UART_SMC{1..2} and UART_SCC{1..4} and SCC_WAIT_CLOSING macros are not used anymore since the above commit. cpm_uart_ports[] isn't used outside cpm_uart_core.c since the same commit, so make it static. cpm_uart_init_smc() and cpm_uart_init_scc() don't need a forward declaration. FLAG_DISCARDING and IS_DISCARDING have never been used since at least 2.6.12 and the start of git repository for kernel. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/96ef20ae1df056d1b7967871ba6e27e5b5aaeea6.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/cpm_uart.h | 21 --------------------- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 4 +--- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h index 46c03ed71c31..687b48fc6fb6 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart.h @@ -25,18 +25,9 @@ struct gpio_desc; #define SERIAL_CPM_MINOR 46 #define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC) -#define IS_DISCARDING(pinfo) (pinfo->flags & FLAG_DISCARDING) -#define FLAG_DISCARDING 0x00000004 /* when set, don't discard */ #define FLAG_SMC 0x00000002 #define FLAG_CONSOLE 0x00000001 -#define UART_SMC1 fsid_smc1_uart -#define UART_SMC2 fsid_smc2_uart -#define UART_SCC1 fsid_scc1_uart -#define UART_SCC2 fsid_scc2_uart -#define UART_SCC3 fsid_scc3_uart -#define UART_SCC4 fsid_scc4_uart - #define UART_NR fs_uart_nr #define RX_NUM_FIFO 4 @@ -44,8 +35,6 @@ struct gpio_desc; #define TX_NUM_FIFO 4 #define TX_BUF_SIZE 32 -#define SCC_WAIT_CLOSING 100 - #define GPIO_CTS 0 #define GPIO_RTS 1 #define GPIO_DCD 2 @@ -85,24 +74,14 @@ struct uart_cpm_port { struct gpio_desc *gpios[NUM_GPIOS]; }; -extern struct uart_cpm_port cpm_uart_ports[UART_NR]; - /* these are located in their respective files */ void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd); void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, struct device_node *np); void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram); -int cpm_uart_init_portdesc(void); int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); void cpm_uart_freebuf(struct uart_cpm_port *pinfo); -void smc1_lineif(struct uart_cpm_port *pinfo); -void smc2_lineif(struct uart_cpm_port *pinfo); -void scc1_lineif(struct uart_cpm_port *pinfo); -void scc2_lineif(struct uart_cpm_port *pinfo); -void scc3_lineif(struct uart_cpm_port *pinfo); -void scc4_lineif(struct uart_cpm_port *pinfo); - /* virtual to phys transtalion */ diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 71366a4cea22..d804dd4019c0 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -48,8 +48,6 @@ /**************************************************************/ static int cpm_uart_tx_pump(struct uart_port *port); -static void cpm_uart_init_smc(struct uart_cpm_port *pinfo); -static void cpm_uart_init_scc(struct uart_cpm_port *pinfo); static void cpm_uart_initbd(struct uart_cpm_port *pinfo); /**************************************************************/ @@ -1128,7 +1126,7 @@ static const struct uart_ops cpm_uart_pops = { #endif }; -struct uart_cpm_port cpm_uart_ports[UART_NR]; +static struct uart_cpm_port cpm_uart_ports[UART_NR]; static int cpm_uart_init_port(struct device_node *np, struct uart_cpm_port *pinfo) -- cgit v1.2.3 From 42ac6998ec878f640768f03ec2d753f32f51d6a4 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:44 +0200 Subject: serial: cpm_uart: Stop using fs_uart_id enum Using an enum indirection to define numeric macros is pointless. Directly use the wanted numeric value. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/4772d2a21894db443fe42836421eb22206a334aa.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/cpm_uart.h | 3 +-- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h index 687b48fc6fb6..c220700df693 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart.h @@ -11,7 +11,6 @@ #define CPM_UART_H #include -#include struct gpio_desc; @@ -28,7 +27,7 @@ struct gpio_desc; #define FLAG_SMC 0x00000002 #define FLAG_CONSOLE 0x00000001 -#define UART_NR fs_uart_nr +#define UART_NR 6 #define RX_NUM_FIFO 4 #define RX_BUF_SIZE 32 diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index d804dd4019c0..c5a896f79d80 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From c2d6c1b4f0349a5d93ebbd8d5311fbbaf1fa54dd Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:45 +0200 Subject: serial: cpm_uart: Use get_baudrate() instead of uart_baudrate() uart_baudrate() is just a trivial wrapper to get_baudrate(). Use get_baudrate() directly and remove assignment in if condition. And also remove uart_clock() which is not used since commit 0b2a2e5b7747 ("cpm_uart: Remove !CONFIG_PPC_CPM_NEW_BINDING code") Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/4d497386f576a3df768e44a04f9bb512e424c311.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/include/asm/fs_pd.h | 10 ---------- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 6 ++++-- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h index 8def56ec05c6..7b61b80f212d 100644 --- a/arch/powerpc/include/asm/fs_pd.h +++ b/arch/powerpc/include/asm/fs_pd.h @@ -36,14 +36,4 @@ extern immap_t __iomem *mpc8xx_immr; #define immr_unmap(addr) do {} while (0) #endif -static inline int uart_baudrate(void) -{ - return get_baudrate(); -} - -static inline int uart_clock(void) -{ - return ppc_proc_freq; -} - #endif diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index c5a896f79d80..36bac4390c13 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -32,10 +32,11 @@ #include #include +#include + #include #include #include -#include #include #include @@ -1311,7 +1312,8 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) if (options) { uart_parse_options(options, &baud, &parity, &bits, &flow); } else { - if ((baud = uart_baudrate()) == -1) + baud = get_baudrate(); + if (baud == -1) baud = 9600; } -- cgit v1.2.3 From 647f5a00d3060297fcfcd0edb026594b313aefed Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:46 +0200 Subject: serial: cpm_uart: Deduplicate cpm_set_{brg/smc_fcr/scc_fcr}() CPMFCR_EB is the same as SMC_EB and is defined for both CPM1 and CPM2. CPMFCR_GBL is defined as 0 for CPM1. Therefore the CPM2 version of cpm_set_scc_fcr() and cpm_set_smc_fcr() can be used on both CPM1 and CPM2. And cpm_set_brg() is already identical and just a wrapper of cpm_setbrg(). In addition those three fonctions are only called once from cpm_uart_core.c, so just replace the calls with the content of the CPM2 versions of them. And DPRAM_BASE is identical so can go in cpm_uart.h. While moving it, use cpm_muram_addr() directly instead of the cpm_dpram_addr() macro and remove __force tag which isn't needed. Then cpm_uart_cpm1.h and cpm_uart_cpm2.h go away. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/6920e61fd362961ae1aeda897c8bfe1efacdc9dc.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/cpm_uart.h | 6 ++++-- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 8 ++++--- drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h | 33 ----------------------------- drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h | 33 ----------------------------- 4 files changed, 9 insertions(+), 71 deletions(-) delete mode 100644 drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h delete mode 100644 drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h index c220700df693..81c1c5f97d19 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart.h @@ -15,11 +15,13 @@ struct gpio_desc; #if defined(CONFIG_CPM2) -#include "cpm_uart_cpm2.h" +#include "asm/cpm2.h" #elif defined(CONFIG_CPM1) -#include "cpm_uart_cpm1.h" +#include "asm/cpm1.h" #endif +#define DPRAM_BASE ((u8 __iomem *)cpm_muram_addr(0)) + #define SERIAL_CPM_MAJOR 204 #define SERIAL_CPM_MINOR 46 diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 36bac4390c13..743892c0e143 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -603,7 +603,7 @@ static void cpm_uart_set_termios(struct uart_port *port, if (pinfo->clk) clk_set_rate(pinfo->clk, baud); else - cpm_set_brg(pinfo->brg - 1, baud); + cpm_setbrg(pinfo->brg - 1, baud); spin_unlock_irqrestore(&port->lock, flags); } @@ -769,7 +769,8 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) * parameter ram. */ - cpm_set_scc_fcr(sup); + out_8(&sup->scc_genscc.scc_rfcr, CPMFCR_GBL | CPMFCR_EB); + out_8(&sup->scc_genscc.scc_tfcr, CPMFCR_GBL | CPMFCR_EB); out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); out_be16(&sup->scc_maxidl, 0x10); @@ -840,7 +841,8 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) /* Set up the uart parameters in the * parameter ram. */ - cpm_set_smc_fcr(up); + out_8(&up->smc_rfcr, CPMFCR_GBL | CPMFCR_EB); + out_8(&up->smc_tfcr, CPMFCR_GBL | CPMFCR_EB); /* Using idle character time requires some additional tuning. */ out_be16(&up->smc_mrblr, pinfo->rx_fifosize); diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h deleted file mode 100644 index 18ec0849918a..000000000000 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Driver for CPM (SCC/SMC) serial ports - * - * definitions for cpm1 - * - */ - -#ifndef CPM_UART_CPM1_H -#define CPM_UART_CPM1_H - -#include - -static inline void cpm_set_brg(int brg, int baud) -{ - cpm_setbrg(brg, baud); -} - -static inline void cpm_set_scc_fcr(scc_uart_t __iomem * sup) -{ - out_8(&sup->scc_genscc.scc_rfcr, SMC_EB); - out_8(&sup->scc_genscc.scc_tfcr, SMC_EB); -} - -static inline void cpm_set_smc_fcr(smc_uart_t __iomem * up) -{ - out_8(&up->smc_rfcr, SMC_EB); - out_8(&up->smc_tfcr, SMC_EB); -} - -#define DPRAM_BASE ((u8 __iomem __force *)cpm_dpram_addr(0)) - -#endif diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h deleted file mode 100644 index 051a8509c3e5..000000000000 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Driver for CPM (SCC/SMC) serial ports - * - * definitions for cpm2 - * - */ - -#ifndef CPM_UART_CPM2_H -#define CPM_UART_CPM2_H - -#include - -static inline void cpm_set_brg(int brg, int baud) -{ - cpm_setbrg(brg, baud); -} - -static inline void cpm_set_scc_fcr(scc_uart_t __iomem *sup) -{ - out_8(&sup->scc_genscc.scc_rfcr, CPMFCR_GBL | CPMFCR_EB); - out_8(&sup->scc_genscc.scc_tfcr, CPMFCR_GBL | CPMFCR_EB); -} - -static inline void cpm_set_smc_fcr(smc_uart_t __iomem *up) -{ - out_8(&up->smc_rfcr, CPMFCR_GBL | CPMFCR_EB); - out_8(&up->smc_tfcr, CPMFCR_GBL | CPMFCR_EB); -} - -#define DPRAM_BASE ((u8 __iomem __force *)cpm_dpram_addr(0)) - -#endif -- cgit v1.2.3 From ae8261ed7e6801131a27868c00cdfc19cda37729 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:47 +0200 Subject: serial: cpm_uart: Deduplicate cpm_line_cr_cmd() cpm_line_cr_cmd() is identical for CPM1 and CPM2 and is used only in cpm_uart_core.c. Move it there. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/6996e6ff93067dcddebf0d0c86487345149e165c.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/cpm_uart.h | 1 - drivers/tty/serial/cpm_uart/cpm_uart_core.c | 5 +++++ drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c | 5 ----- drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c | 5 ----- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h index 81c1c5f97d19..1b5523474ab4 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart.h @@ -76,7 +76,6 @@ struct uart_cpm_port { }; /* these are located in their respective files */ -void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd); void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, struct device_node *np); void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram); diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 743892c0e143..e6f3e4da3144 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -54,6 +54,11 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); #define HW_BUF_SPD_THRESHOLD 2400 +static void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) +{ + cpm_command(port->command, cmd); +} + /* * Check, if transmit buffers are processed */ diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c index 56fc527015cb..b5680376ff3c 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c @@ -36,11 +36,6 @@ /**************************************************************/ -void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) -{ - cpm_command(port->command, cmd); -} - void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, struct device_node *np) { diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c index 108af254e8f3..35f539fcfde8 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c @@ -33,11 +33,6 @@ /**************************************************************/ -void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) -{ - cpm_command(port->command, cmd); -} - void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, struct device_node *np) { -- cgit v1.2.3 From 86f0a9c8e3de2341e5d1150a3d0dfae72de38a4a Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:48 +0200 Subject: serial: cpm_uart: Refactor cpm_uart_allocbuf()/cpm_uart_freebuf() cpm_uart_freebuf() is identical for CPM1 and CPM2. cpm_uart_allocbuf() only has a small difference between CPM1 and CPM2 as shown below: CPM1: if (is_con) { /* was hostalloc but changed cause it blows away the */ /* large tlb mapping when pinning the kernel area */ mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); dma_addr = (u32)cpm_dpram_phys(mem_addr); } else mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, GFP_KERNEL); CPM2: if (is_con) { mem_addr = kzalloc(memsz, GFP_NOWAIT); dma_addr = virt_to_bus(mem_addr); } else mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, GFP_KERNEL); Refactor this by using IS_ENABLED(CONFIG_CPM1) and move both functions in cpm_uart_core.c as they are used only there. While doing this, add the necessary casts to silence sparse for the CPM1 part. This is because a dma alloc is not expected to be an iomem but for CPM1 as we use DPRAM this is seen as iomem. Also replace calls to cpm_dpxxxx() by relevant cpm_muram_xxxx() calls. This is needed at least for cpm_dpram_phys() which is only defined for CPM1. Just do the same for all so that cpm_dpxxxx() macros can get droped in the future. To silence checkpatch, replace printk(KERN_ERR by pr_err( and display function name instead of hard coded filename. Also replace mem_addr == NULL by !mem_addr. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/606dfdd258a4f2f2882e2e189bef37526bb3b499.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/cpm_uart.h | 2 - drivers/tty/serial/cpm_uart/cpm_uart_core.c | 72 +++++++++++++++++++++++++++++ drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c | 69 --------------------------- drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c | 69 --------------------------- 4 files changed, 72 insertions(+), 140 deletions(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h index 1b5523474ab4..6d6046d45bec 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart.h @@ -79,8 +79,6 @@ struct uart_cpm_port { void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, struct device_node *np); void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram); -int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); -void cpm_uart_freebuf(struct uart_cpm_port *pinfo); /* virtual to phys transtalion diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index e6f3e4da3144..fa5466518536 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -868,6 +868,78 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN); } +/* + * Allocate DP-Ram and memory buffers. We need to allocate a transmit and + * receive buffer descriptors from dual port ram, and a character + * buffer area from host mem. If we are allocating for the console we need + * to do it from bootmem + */ +static int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) +{ + int dpmemsz, memsz; + u8 __iomem *dp_mem; + unsigned long dp_offset; + u8 *mem_addr; + dma_addr_t dma_addr = 0; + + pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); + + dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); + dp_offset = cpm_muram_alloc(dpmemsz, 8); + if (IS_ERR_VALUE(dp_offset)) { + pr_err("%s: could not allocate buffer descriptors\n", __func__); + return -ENOMEM; + } + + dp_mem = cpm_muram_addr(dp_offset); + + memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); + if (IS_ENABLED(CONFIG_CPM1) && is_con) { + /* was hostalloc but changed cause it blows away the */ + /* large tlb mapping when pinning the kernel area */ + mem_addr = (u8 __force *)cpm_muram_addr(cpm_muram_alloc(memsz, 8)); + dma_addr = cpm_muram_dma((void __iomem *)mem_addr); + } else if (is_con) { + mem_addr = kzalloc(memsz, GFP_NOWAIT); + dma_addr = virt_to_bus(mem_addr); + } else { + mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, + GFP_KERNEL); + } + + if (!mem_addr) { + cpm_muram_free(dp_offset); + pr_err("%s: could not allocate coherent memory\n", __func__); + return -ENOMEM; + } + + pinfo->dp_addr = dp_offset; + pinfo->mem_addr = mem_addr; + pinfo->dma_addr = dma_addr; + pinfo->mem_size = memsz; + + pinfo->rx_buf = mem_addr; + pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos + * pinfo->rx_fifosize); + + pinfo->rx_bd_base = (cbd_t __iomem *)dp_mem; + pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; + + return 0; +} + +static void cpm_uart_freebuf(struct uart_cpm_port *pinfo) +{ + dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos * + pinfo->rx_fifosize) + + L1_CACHE_ALIGN(pinfo->tx_nrfifos * + pinfo->tx_fifosize), (void __force *)pinfo->mem_addr, + pinfo->dma_addr); + + cpm_muram_free(pinfo->dp_addr); +} + /* * Initialize port. This is called from early_console stuff * so we have to be careful here ! diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c index b5680376ff3c..3fe436dc2f95 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c @@ -46,72 +46,3 @@ void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) { iounmap(pram); } - -/* - * Allocate DP-Ram and memory buffers. We need to allocate a transmit and - * receive buffer descriptors from dual port ram, and a character - * buffer area from host mem. If we are allocating for the console we need - * to do it from bootmem - */ -int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) -{ - int dpmemsz, memsz; - u8 *dp_mem; - unsigned long dp_offset; - u8 *mem_addr; - dma_addr_t dma_addr = 0; - - pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); - - dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); - dp_offset = cpm_dpalloc(dpmemsz, 8); - if (IS_ERR_VALUE(dp_offset)) { - printk(KERN_ERR - "cpm_uart_cpm1.c: could not allocate buffer descriptors\n"); - return -ENOMEM; - } - dp_mem = cpm_dpram_addr(dp_offset); - - memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + - L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); - if (is_con) { - /* was hostalloc but changed cause it blows away the */ - /* large tlb mapping when pinning the kernel area */ - mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); - dma_addr = (u32)cpm_dpram_phys(mem_addr); - } else - mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, - GFP_KERNEL); - - if (mem_addr == NULL) { - cpm_dpfree(dp_offset); - printk(KERN_ERR - "cpm_uart_cpm1.c: could not allocate coherent memory\n"); - return -ENOMEM; - } - - pinfo->dp_addr = dp_offset; - pinfo->mem_addr = mem_addr; /* virtual address*/ - pinfo->dma_addr = dma_addr; /* physical address*/ - pinfo->mem_size = memsz; - - pinfo->rx_buf = mem_addr; - pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos - * pinfo->rx_fifosize); - - pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem; - pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; - - return 0; -} - -void cpm_uart_freebuf(struct uart_cpm_port *pinfo) -{ - dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos * - pinfo->rx_fifosize) + - L1_CACHE_ALIGN(pinfo->tx_nrfifos * - pinfo->tx_fifosize), pinfo->mem_addr, - pinfo->dma_addr); - - cpm_dpfree(pinfo->dp_addr); -} diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c index 35f539fcfde8..09d46255aa9d 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c @@ -80,72 +80,3 @@ void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) if (!IS_SMC(port)) iounmap(pram); } - -/* - * Allocate DP-Ram and memory buffers. We need to allocate a transmit and - * receive buffer descriptors from dual port ram, and a character - * buffer area from host mem. If we are allocating for the console we need - * to do it from bootmem - */ -int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) -{ - int dpmemsz, memsz; - u8 __iomem *dp_mem; - unsigned long dp_offset; - u8 *mem_addr; - dma_addr_t dma_addr = 0; - - pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); - - dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); - dp_offset = cpm_dpalloc(dpmemsz, 8); - if (IS_ERR_VALUE(dp_offset)) { - printk(KERN_ERR - "cpm_uart_cpm.c: could not allocate buffer descriptors\n"); - return -ENOMEM; - } - - dp_mem = cpm_dpram_addr(dp_offset); - - memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + - L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); - if (is_con) { - mem_addr = kzalloc(memsz, GFP_NOWAIT); - dma_addr = virt_to_bus(mem_addr); - } - else - mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, - GFP_KERNEL); - - if (mem_addr == NULL) { - cpm_dpfree(dp_offset); - printk(KERN_ERR - "cpm_uart_cpm.c: could not allocate coherent memory\n"); - return -ENOMEM; - } - - pinfo->dp_addr = dp_offset; - pinfo->mem_addr = mem_addr; - pinfo->dma_addr = dma_addr; - pinfo->mem_size = memsz; - - pinfo->rx_buf = mem_addr; - pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos - * pinfo->rx_fifosize); - - pinfo->rx_bd_base = (cbd_t __iomem *)dp_mem; - pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; - - return 0; -} - -void cpm_uart_freebuf(struct uart_cpm_port *pinfo) -{ - dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos * - pinfo->rx_fifosize) + - L1_CACHE_ALIGN(pinfo->tx_nrfifos * - pinfo->tx_fifosize), (void __force *)pinfo->mem_addr, - pinfo->dma_addr); - - cpm_dpfree(pinfo->dp_addr); -} -- cgit v1.2.3 From 8d1bd031ba152115461b3326eb3bdf7ca1f9bb3d Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:49 +0200 Subject: serial: cpm_uart: Refactor cpm_uart_[un]map_pram() cpm_uart_map_pram() and cpm_uart_unmap_pram() are very similar for CPM1 and CPM2. On CPM1 cpm_uart_map_pram() uses of_iomap() while CPM2 uses of_address_to_resource()/ioremap(). CPM2 version will also work on CPM1. On CPM2 cpm_uart_map_pram() and cpm_uart_unmap_pram() has a special handling for SMC. Just gate it by an IS_ENABLED(CONFIG_CPM2). So move the CPM2 version into cpm_uart_core.c which is the only user of those two fonctions and refactor to also handle CPM1 as mentionned above. PROFF_SMC_SIZE is only defined for SMC2 and used only there. To make it simple, just use the numerical value 64, this is the only place it is used and anyway there's already the same numerical value for the alignment. Use cpm_muram_alloc() instead of cpm_dpalloc() macro. Then cpm_uart_cpm1.c and cpm_uart_cpm2.c are now empty and go away. Replace printk(KERN_WARN by pr_warn( to make checkpatch happier. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/44a266106c421319aa8e700c2db52d5dcd652c0f.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/cpm_uart/Makefile | 8 +-- drivers/tty/serial/cpm_uart/cpm_uart.h | 5 -- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 48 +++++++++++++++++ drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c | 48 ----------------- drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c | 82 ----------------------------- 5 files changed, 49 insertions(+), 142 deletions(-) delete mode 100644 drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c delete mode 100644 drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c diff --git a/drivers/tty/serial/cpm_uart/Makefile b/drivers/tty/serial/cpm_uart/Makefile index 3f3a6ed02ed4..91f202fa5251 100644 --- a/drivers/tty/serial/cpm_uart/Makefile +++ b/drivers/tty/serial/cpm_uart/Makefile @@ -3,10 +3,4 @@ # Makefile for the Motorola 8xx FEC ethernet controller # -obj-$(CONFIG_SERIAL_CPM) += cpm_uart.o - -# Select the correct platform objects. -cpm_uart-objs-$(CONFIG_CPM2) += cpm_uart_cpm2.o -cpm_uart-objs-$(CONFIG_CPM1) += cpm_uart_cpm1.o - -cpm_uart-objs := cpm_uart_core.o $(cpm_uart-objs-y) +obj-$(CONFIG_SERIAL_CPM) += cpm_uart_core.o diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h index 6d6046d45bec..37bb6e976e03 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart.h @@ -75,11 +75,6 @@ struct uart_cpm_port { struct gpio_desc *gpios[NUM_GPIOS]; }; -/* these are located in their respective files */ -void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, - struct device_node *np); -void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram); - /* virtual to phys transtalion */ diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index fa5466518536..626423022d62 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1207,6 +1207,54 @@ static const struct uart_ops cpm_uart_pops = { static struct uart_cpm_port cpm_uart_ports[UART_NR]; +static void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, + struct device_node *np) +{ + void __iomem *pram; + unsigned long offset; + struct resource res; + resource_size_t len; + + /* Don't remap parameter RAM if it has already been initialized + * during console setup. + */ + if (IS_SMC(port) && port->smcup) + return port->smcup; + else if (!IS_SMC(port) && port->sccup) + return port->sccup; + + if (of_address_to_resource(np, 1, &res)) + return NULL; + + len = resource_size(&res); + pram = ioremap(res.start, len); + if (!pram) + return NULL; + + if (!IS_ENABLED(CONFIG_CPM2) || !IS_SMC(port)) + return pram; + + if (len != 2) { + pr_warn("cpm_uart[%d]: device tree references " + "SMC pram, using boot loader/wrapper pram mapping. " + "Please fix your device tree to reference the pram " + "base register instead.\n", + port->port.line); + return pram; + } + + offset = cpm_muram_alloc(64, 64); + out_be16(pram, offset); + iounmap(pram); + return cpm_muram_addr(offset); +} + +static void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) +{ + if (!IS_ENABLED(CONFIG_CPM2) || !IS_SMC(port)) + iounmap(pram); +} + static int cpm_uart_init_port(struct device_node *np, struct uart_cpm_port *pinfo) { diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c deleted file mode 100644 index 3fe436dc2f95..000000000000 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for CPM (SCC/SMC) serial ports; CPM1 definitions - * - * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) - * Pantelis Antoniou (panto@intracom.gr) (CPM1) - * - * Copyright (C) 2004 Freescale Semiconductor, Inc. - * (C) 2004 Intracom, S.A. - * (C) 2006 MontaVista Software, Inc. - * Vitaly Bordug - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include - -#include "cpm_uart.h" - -/**************************************************************/ - -void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, - struct device_node *np) -{ - return of_iomap(np, 1); -} - -void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) -{ - iounmap(pram); -} diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c deleted file mode 100644 index 09d46255aa9d..000000000000 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for CPM (SCC/SMC) serial ports; CPM2 definitions - * - * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) - * Pantelis Antoniou (panto@intracom.gr) (CPM1) - * - * Copyright (C) 2004 Freescale Semiconductor, Inc. - * (C) 2004 Intracom, S.A. - * (C) 2006 MontaVista Software, Inc. - * Vitaly Bordug - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "cpm_uart.h" - -/**************************************************************/ - -void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, - struct device_node *np) -{ - void __iomem *pram; - unsigned long offset; - struct resource res; - resource_size_t len; - - /* Don't remap parameter RAM if it has already been initialized - * during console setup. - */ - if (IS_SMC(port) && port->smcup) - return port->smcup; - else if (!IS_SMC(port) && port->sccup) - return port->sccup; - - if (of_address_to_resource(np, 1, &res)) - return NULL; - - len = resource_size(&res); - pram = ioremap(res.start, len); - if (!pram) - return NULL; - - if (!IS_SMC(port)) - return pram; - - if (len != 2) { - printk(KERN_WARNING "cpm_uart[%d]: device tree references " - "SMC pram, using boot loader/wrapper pram mapping. " - "Please fix your device tree to reference the pram " - "base register instead.\n", - port->port.line); - return pram; - } - - offset = cpm_dpalloc(PROFF_SMC_SIZE, 64); - out_be16(pram, offset); - iounmap(pram); - return cpm_muram_addr(offset); -} - -void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) -{ - if (!IS_SMC(port)) - iounmap(pram); -} -- cgit v1.2.3 From dbae4258d156e1c698bdd6deb56e13aa4d4e55cc Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:50 +0200 Subject: serial: cpm_uart: Remove cpm_uart/ subdirectory cpm_uart/ subdirectory only has cpm_uart_core.c and cpm_uart.h now. Move them up and remove cpm_uart/ directory while renaming cpm_uart_core.c as cpm_uart.c Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/9b8b8f89fc386480030f5339abe307541ae436a6.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Makefile | 2 +- drivers/tty/serial/cpm_uart.c | 1612 +++++++++++++++++++++++++++ drivers/tty/serial/cpm_uart.h | 114 ++ drivers/tty/serial/cpm_uart/Makefile | 6 - drivers/tty/serial/cpm_uart/cpm_uart.h | 114 -- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 1612 --------------------------- 6 files changed, 1727 insertions(+), 1733 deletions(-) create mode 100644 drivers/tty/serial/cpm_uart.c create mode 100644 drivers/tty/serial/cpm_uart.h delete mode 100644 drivers/tty/serial/cpm_uart/Makefile delete mode 100644 drivers/tty/serial/cpm_uart/cpm_uart.h delete mode 100644 drivers/tty/serial/cpm_uart/cpm_uart_core.c diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index d4123469583d..138abbc89738 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -41,7 +41,7 @@ obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o obj-$(CONFIG_SERIAL_DZ) += dz.o obj-$(CONFIG_SERIAL_ZS) += zs.o obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o -obj-$(CONFIG_SERIAL_CPM) += cpm_uart/ +obj-$(CONFIG_SERIAL_CPM) += cpm_uart.o obj-$(CONFIG_SERIAL_IMX) += imx.o obj-$(CONFIG_SERIAL_IMX_EARLYCON) += imx_earlycon.o obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o diff --git a/drivers/tty/serial/cpm_uart.c b/drivers/tty/serial/cpm_uart.c new file mode 100644 index 000000000000..626423022d62 --- /dev/null +++ b/drivers/tty/serial/cpm_uart.c @@ -0,0 +1,1612 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for CPM (SCC/SMC) serial ports; core driver + * + * Based on arch/ppc/cpm2_io/uart.c by Dan Malek + * Based on ppc8xx.c by Thomas Gleixner + * Based on drivers/serial/amba.c by Russell King + * + * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) + * Pantelis Antoniou (panto@intracom.gr) (CPM1) + * + * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc. + * (C) 2004 Intracom, S.A. + * (C) 2005-2006 MontaVista Software, Inc. + * Vitaly Bordug + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include "cpm_uart.h" + + +/**************************************************************/ + +static int cpm_uart_tx_pump(struct uart_port *port); +static void cpm_uart_initbd(struct uart_cpm_port *pinfo); + +/**************************************************************/ + +#define HW_BUF_SPD_THRESHOLD 2400 + +static void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) +{ + cpm_command(port->command, cmd); +} + +/* + * Check, if transmit buffers are processed +*/ +static unsigned int cpm_uart_tx_empty(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + cbd_t __iomem *bdp = pinfo->tx_bd_base; + int ret = 0; + + while (1) { + if (in_be16(&bdp->cbd_sc) & BD_SC_READY) + break; + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) { + ret = TIOCSER_TEMT; + break; + } + bdp++; + } + + pr_debug("CPM uart[%d]:tx_empty: %d\n", port->line, ret); + + return ret; +} + +static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + + if (pinfo->gpios[GPIO_RTS]) + gpiod_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS)); + + if (pinfo->gpios[GPIO_DTR]) + gpiod_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR)); +} + +static unsigned int cpm_uart_get_mctrl(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; + + if (pinfo->gpios[GPIO_CTS]) { + if (gpiod_get_value(pinfo->gpios[GPIO_CTS])) + mctrl &= ~TIOCM_CTS; + } + + if (pinfo->gpios[GPIO_DSR]) { + if (gpiod_get_value(pinfo->gpios[GPIO_DSR])) + mctrl &= ~TIOCM_DSR; + } + + if (pinfo->gpios[GPIO_DCD]) { + if (gpiod_get_value(pinfo->gpios[GPIO_DCD])) + mctrl &= ~TIOCM_CAR; + } + + if (pinfo->gpios[GPIO_RI]) { + if (!gpiod_get_value(pinfo->gpios[GPIO_RI])) + mctrl |= TIOCM_RNG; + } + + return mctrl; +} + +/* + * Stop transmitter + */ +static void cpm_uart_stop_tx(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; + + pr_debug("CPM uart[%d]:stop tx\n", port->line); + + if (IS_SMC(pinfo)) + clrbits8(&smcp->smc_smcm, SMCM_TX); + else + clrbits16(&sccp->scc_sccm, UART_SCCM_TX); +} + +/* + * Start transmitter + */ +static void cpm_uart_start_tx(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; + + pr_debug("CPM uart[%d]:start tx\n", port->line); + + if (IS_SMC(pinfo)) { + if (in_8(&smcp->smc_smcm) & SMCM_TX) + return; + } else { + if (in_be16(&sccp->scc_sccm) & UART_SCCM_TX) + return; + } + + if (cpm_uart_tx_pump(port) != 0) { + if (IS_SMC(pinfo)) { + setbits8(&smcp->smc_smcm, SMCM_TX); + } else { + setbits16(&sccp->scc_sccm, UART_SCCM_TX); + } + } +} + +/* + * Stop receiver + */ +static void cpm_uart_stop_rx(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; + + pr_debug("CPM uart[%d]:stop rx\n", port->line); + + if (IS_SMC(pinfo)) + clrbits8(&smcp->smc_smcm, SMCM_RX); + else + clrbits16(&sccp->scc_sccm, UART_SCCM_RX); +} + +/* + * Generate a break. + */ +static void cpm_uart_break_ctl(struct uart_port *port, int break_state) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + + pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, + break_state); + + if (break_state) + cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); + else + cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); +} + +/* + * Transmit characters, refill buffer descriptor, if possible + */ +static void cpm_uart_int_tx(struct uart_port *port) +{ + pr_debug("CPM uart[%d]:TX INT\n", port->line); + + cpm_uart_tx_pump(port); +} + +#ifdef CONFIG_CONSOLE_POLL +static int serial_polled; +#endif + +/* + * Receive characters + */ +static void cpm_uart_int_rx(struct uart_port *port) +{ + int i; + unsigned char ch; + u8 *cp; + struct tty_port *tport = &port->state->port; + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + cbd_t __iomem *bdp; + u16 status; + unsigned int flg; + + pr_debug("CPM uart[%d]:RX INT\n", port->line); + + /* Just loop through the closed BDs and copy the characters into + * the buffer. + */ + bdp = pinfo->rx_cur; + for (;;) { +#ifdef CONFIG_CONSOLE_POLL + if (unlikely(serial_polled)) { + serial_polled = 0; + return; + } +#endif + /* get status */ + status = in_be16(&bdp->cbd_sc); + /* If this one is empty, return happy */ + if (status & BD_SC_EMPTY) + break; + + /* get number of characters, and check spce in flip-buffer */ + i = in_be16(&bdp->cbd_datlen); + + /* If we have not enough room in tty flip buffer, then we try + * later, which will be the next rx-interrupt or a timeout + */ + if (tty_buffer_request_room(tport, i) < i) { + printk(KERN_WARNING "No room in flip buffer\n"); + return; + } + + /* get pointer */ + cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); + + /* loop through the buffer */ + while (i-- > 0) { + ch = *cp++; + port->icount.rx++; + flg = TTY_NORMAL; + + if (status & + (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) + goto handle_error; + if (uart_handle_sysrq_char(port, ch)) + continue; +#ifdef CONFIG_CONSOLE_POLL + if (unlikely(serial_polled)) { + serial_polled = 0; + return; + } +#endif + error_return: + tty_insert_flip_char(tport, ch, flg); + + } /* End while (i--) */ + + /* This BD is ready to be used again. Clear status. get next */ + clrbits16(&bdp->cbd_sc, BD_SC_BR | BD_SC_FR | BD_SC_PR | + BD_SC_OV | BD_SC_ID); + setbits16(&bdp->cbd_sc, BD_SC_EMPTY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = pinfo->rx_bd_base; + else + bdp++; + + } /* End for (;;) */ + + /* Write back buffer pointer */ + pinfo->rx_cur = bdp; + + /* activate BH processing */ + tty_flip_buffer_push(tport); + + return; + + /* Error processing */ + + handle_error: + /* Statistics */ + if (status & BD_SC_BR) + port->icount.brk++; + if (status & BD_SC_PR) + port->icount.parity++; + if (status & BD_SC_FR) + port->icount.frame++; + if (status & BD_SC_OV) + port->icount.overrun++; + + /* Mask out ignored conditions */ + status &= port->read_status_mask; + + /* Handle the remaining ones */ + if (status & BD_SC_BR) + flg = TTY_BREAK; + else if (status & BD_SC_PR) + flg = TTY_PARITY; + else if (status & BD_SC_FR) + flg = TTY_FRAME; + + /* overrun does not affect the current character ! */ + if (status & BD_SC_OV) { + ch = 0; + flg = TTY_OVERRUN; + /* We skip this buffer */ + /* CHECK: Is really nothing senseful there */ + /* ASSUMPTION: it contains nothing valid */ + i = 0; + } + port->sysrq = 0; + goto error_return; +} + +/* + * Asynchron mode interrupt handler + */ +static irqreturn_t cpm_uart_int(int irq, void *data) +{ + u8 events; + struct uart_port *port = data; + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; + + pr_debug("CPM uart[%d]:IRQ\n", port->line); + + if (IS_SMC(pinfo)) { + events = in_8(&smcp->smc_smce); + out_8(&smcp->smc_smce, events); + if (events & SMCM_BRKE) + uart_handle_break(port); + if (events & SMCM_RX) + cpm_uart_int_rx(port); + if (events & SMCM_TX) + cpm_uart_int_tx(port); + } else { + events = in_be16(&sccp->scc_scce); + out_be16(&sccp->scc_scce, events); + if (events & UART_SCCM_BRKE) + uart_handle_break(port); + if (events & UART_SCCM_RX) + cpm_uart_int_rx(port); + if (events & UART_SCCM_TX) + cpm_uart_int_tx(port); + } + return (events) ? IRQ_HANDLED : IRQ_NONE; +} + +static int cpm_uart_startup(struct uart_port *port) +{ + int retval; + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + + pr_debug("CPM uart[%d]:startup\n", port->line); + + /* If the port is not the console, make sure rx is disabled. */ + if (!(pinfo->flags & FLAG_CONSOLE)) { + /* Disable UART rx */ + if (IS_SMC(pinfo)) { + clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN); + clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX); + } else { + clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR); + clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); + } + cpm_uart_initbd(pinfo); + if (IS_SMC(pinfo)) { + out_be32(&pinfo->smcup->smc_rstate, 0); + out_be32(&pinfo->smcup->smc_tstate, 0); + out_be16(&pinfo->smcup->smc_rbptr, + in_be16(&pinfo->smcup->smc_rbase)); + out_be16(&pinfo->smcup->smc_tbptr, + in_be16(&pinfo->smcup->smc_tbase)); + } else { + cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); + } + } + /* Install interrupt handler. */ + retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); + if (retval) + return retval; + + /* Startup rx-int */ + if (IS_SMC(pinfo)) { + setbits8(&pinfo->smcp->smc_smcm, SMCM_RX); + setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN)); + } else { + setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); + setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT)); + } + + return 0; +} + +inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(pinfo->wait_closing); +} + +/* + * Shutdown the uart + */ +static void cpm_uart_shutdown(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + + pr_debug("CPM uart[%d]:shutdown\n", port->line); + + /* free interrupt handler */ + free_irq(port->irq, port); + + /* If the port is not the console, disable Rx and Tx. */ + if (!(pinfo->flags & FLAG_CONSOLE)) { + /* Wait for all the BDs marked sent */ + while(!cpm_uart_tx_empty(port)) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(2); + } + + if (pinfo->wait_closing) + cpm_uart_wait_until_send(pinfo); + + /* Stop uarts */ + if (IS_SMC(pinfo)) { + smc_t __iomem *smcp = pinfo->smcp; + clrbits16(&smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); + clrbits8(&smcp->smc_smcm, SMCM_RX | SMCM_TX); + } else { + scc_t __iomem *sccp = pinfo->sccp; + clrbits32(&sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); + clrbits16(&sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); + } + + /* Shut them really down and reinit buffer descriptors */ + if (IS_SMC(pinfo)) { + out_be16(&pinfo->smcup->smc_brkcr, 0); + cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); + } else { + out_be16(&pinfo->sccup->scc_brkcr, 0); + cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); + } + + cpm_uart_initbd(pinfo); + } +} + +static void cpm_uart_set_termios(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old) +{ + int baud; + unsigned long flags; + u16 cval, scval, prev_mode; + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; + int maxidl; + + pr_debug("CPM uart[%d]:set_termios\n", port->line); + + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); + if (baud < HW_BUF_SPD_THRESHOLD || port->flags & UPF_LOW_LATENCY) + pinfo->rx_fifosize = 1; + else + pinfo->rx_fifosize = RX_BUF_SIZE; + + /* MAXIDL is the timeout after which a receive buffer is closed + * when not full if no more characters are received. + * We calculate it from the baudrate so that the duration is + * always the same at standard rates: about 4ms. + */ + maxidl = baud / 2400; + if (maxidl < 1) + maxidl = 1; + if (maxidl > 0x10) + maxidl = 0x10; + + cval = 0; + scval = 0; + + if (termios->c_cflag & CSTOPB) { + cval |= SMCMR_SL; /* Two stops */ + scval |= SCU_PSMR_SL; + } + + if (termios->c_cflag & PARENB) { + cval |= SMCMR_PEN; + scval |= SCU_PSMR_PEN; + if (!(termios->c_cflag & PARODD)) { + cval |= SMCMR_PM_EVEN; + scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP); + } + } + + /* + * Update the timeout + */ + uart_update_timeout(port, termios->c_cflag, baud); + + /* + * Set up parity check flag + */ + port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); + if (termios->c_iflag & INPCK) + port->read_status_mask |= BD_SC_FR | BD_SC_PR; + if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK)) + port->read_status_mask |= BD_SC_BR; + + /* + * Characters to ignore + */ + port->ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; + if (termios->c_iflag & IGNBRK) { + port->ignore_status_mask |= BD_SC_BR; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= BD_SC_OV; + } + /* + * !!! ignore all characters if CREAD is not set + */ + if ((termios->c_cflag & CREAD) == 0) + port->read_status_mask &= ~BD_SC_EMPTY; + + spin_lock_irqsave(&port->lock, flags); + + if (IS_SMC(pinfo)) { + unsigned int bits = tty_get_frame_size(termios->c_cflag); + + /* + * MRBLR can be changed while an SMC/SCC is operating only + * if it is done in a single bus cycle with one 16-bit move + * (not two 8-bit bus cycles back-to-back). This occurs when + * the cp shifts control to the next RxBD, so the change does + * not take effect immediately. To guarantee the exact RxBD + * on which the change occurs, change MRBLR only while the + * SMC/SCC receiver is disabled. + */ + out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize); + out_be16(&pinfo->smcup->smc_maxidl, maxidl); + + /* Set the mode register. We want to keep a copy of the + * enables, because we want to put them back if they were + * present. + */ + prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN); + /* Output in *one* operation, so we don't interrupt RX/TX if they + * were already enabled. + * Character length programmed into the register is frame bits minus 1. + */ + out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits - 1) | cval | + SMCMR_SM_UART | prev_mode); + } else { + unsigned int bits = tty_get_char_size(termios->c_cflag); + + out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); + out_be16(&pinfo->sccup->scc_maxidl, maxidl); + out_be16(&sccp->scc_psmr, (UART_LCR_WLEN(bits) << 12) | scval); + } + + if (pinfo->clk) + clk_set_rate(pinfo->clk, baud); + else + cpm_setbrg(pinfo->brg - 1, baud); + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *cpm_uart_type(struct uart_port *port) +{ + pr_debug("CPM uart[%d]:uart_type\n", port->line); + + return port->type == PORT_CPM ? "CPM UART" : NULL; +} + +/* + * verify the new serial_struct (for TIOCSSERIAL). + */ +static int cpm_uart_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + int ret = 0; + + pr_debug("CPM uart[%d]:verify_port\n", port->line); + + if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) + ret = -EINVAL; + if (ser->irq < 0 || ser->irq >= nr_irqs) + ret = -EINVAL; + if (ser->baud_base < 9600) + ret = -EINVAL; + return ret; +} + +/* + * Transmit characters, refill buffer descriptor, if possible + */ +static int cpm_uart_tx_pump(struct uart_port *port) +{ + cbd_t __iomem *bdp; + u8 *p; + int count; + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + struct circ_buf *xmit = &port->state->xmit; + + /* Handle xon/xoff */ + if (port->x_char) { + /* Pick next descriptor and fill from buffer */ + bdp = pinfo->tx_cur; + + p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); + + *p++ = port->x_char; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + /* Get next BD. */ + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = pinfo->tx_bd_base; + else + bdp++; + pinfo->tx_cur = bdp; + + port->icount.tx++; + port->x_char = 0; + return 1; + } + + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + cpm_uart_stop_tx(port); + return 0; + } + + /* Pick next descriptor and fill from buffer */ + bdp = pinfo->tx_cur; + + while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && !uart_circ_empty(xmit)) { + count = 0; + p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); + while (count < pinfo->tx_fifosize) { + *p++ = xmit->buf[xmit->tail]; + uart_xmit_advance(port, 1); + count++; + if (uart_circ_empty(xmit)) + break; + } + out_be16(&bdp->cbd_datlen, count); + setbits16(&bdp->cbd_sc, BD_SC_READY); + /* Get next BD. */ + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = pinfo->tx_bd_base; + else + bdp++; + } + pinfo->tx_cur = bdp; + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (uart_circ_empty(xmit)) { + cpm_uart_stop_tx(port); + return 0; + } + + return 1; +} + +/* + * init buffer descriptors + */ +static void cpm_uart_initbd(struct uart_cpm_port *pinfo) +{ + int i; + u8 *mem_addr; + cbd_t __iomem *bdp; + + pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line); + + /* Set the physical address of the host memory + * buffers in the buffer descriptors, and the + * virtual address for us to work with. + */ + mem_addr = pinfo->mem_addr; + bdp = pinfo->rx_cur = pinfo->rx_bd_base; + for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { + out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); + out_be16(&bdp->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT); + mem_addr += pinfo->rx_fifosize; + } + + out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); + out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT); + + /* Set the physical address of the host memory + * buffers in the buffer descriptors, and the + * virtual address for us to work with. + */ + mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); + bdp = pinfo->tx_cur = pinfo->tx_bd_base; + for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { + out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); + out_be16(&bdp->cbd_sc, BD_SC_INTRPT); + mem_addr += pinfo->tx_fifosize; + } + + out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); + out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_INTRPT); +} + +static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) +{ + scc_t __iomem *scp; + scc_uart_t __iomem *sup; + + pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line); + + scp = pinfo->sccp; + sup = pinfo->sccup; + + /* Store address */ + out_be16(&pinfo->sccup->scc_genscc.scc_rbase, + (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); + out_be16(&pinfo->sccup->scc_genscc.scc_tbase, + (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); + + /* Set up the uart parameters in the + * parameter ram. + */ + + out_8(&sup->scc_genscc.scc_rfcr, CPMFCR_GBL | CPMFCR_EB); + out_8(&sup->scc_genscc.scc_tfcr, CPMFCR_GBL | CPMFCR_EB); + + out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); + out_be16(&sup->scc_maxidl, 0x10); + out_be16(&sup->scc_brkcr, 1); + out_be16(&sup->scc_parec, 0); + out_be16(&sup->scc_frmec, 0); + out_be16(&sup->scc_nosec, 0); + out_be16(&sup->scc_brkec, 0); + out_be16(&sup->scc_uaddr1, 0); + out_be16(&sup->scc_uaddr2, 0); + out_be16(&sup->scc_toseq, 0); + out_be16(&sup->scc_char1, 0x8000); + out_be16(&sup->scc_char2, 0x8000); + out_be16(&sup->scc_char3, 0x8000); + out_be16(&sup->scc_char4, 0x8000); + out_be16(&sup->scc_char5, 0x8000); + out_be16(&sup->scc_char6, 0x8000); + out_be16(&sup->scc_char7, 0x8000); + out_be16(&sup->scc_char8, 0x8000); + out_be16(&sup->scc_rccm, 0xc0ff); + + /* Send the CPM an initialize command. + */ + cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + out_be32(&scp->scc_gsmrh, 0); + out_be32(&scp->scc_gsmrl, + SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); + + /* Enable rx interrupts and clear all pending events. */ + out_be16(&scp->scc_sccm, 0); + out_be16(&scp->scc_scce, 0xffff); + out_be16(&scp->scc_dsr, 0x7e7e); + out_be16(&scp->scc_psmr, 0x3000); + + setbits32(&scp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); +} + +static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) +{ + smc_t __iomem *sp; + smc_uart_t __iomem *up; + + pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); + + sp = pinfo->smcp; + up = pinfo->smcup; + + /* Store address */ + out_be16(&pinfo->smcup->smc_rbase, + (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); + out_be16(&pinfo->smcup->smc_tbase, + (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); + +/* + * In case SMC is being relocated... + */ + out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase)); + out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase)); + out_be32(&up->smc_rstate, 0); + out_be32(&up->smc_tstate, 0); + out_be16(&up->smc_brkcr, 1); /* number of break chars */ + out_be16(&up->smc_brkec, 0); + + /* Set up the uart parameters in the + * parameter ram. + */ + out_8(&up->smc_rfcr, CPMFCR_GBL | CPMFCR_EB); + out_8(&up->smc_tfcr, CPMFCR_GBL | CPMFCR_EB); + + /* Using idle character time requires some additional tuning. */ + out_be16(&up->smc_mrblr, pinfo->rx_fifosize); + out_be16(&up->smc_maxidl, 0x10); + out_be16(&up->smc_brklen, 0); + out_be16(&up->smc_brkec, 0); + out_be16(&up->smc_brkcr, 1); + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART); + + /* Enable only rx interrupts clear all pending events. */ + out_8(&sp->smc_smcm, 0); + out_8(&sp->smc_smce, 0xff); + + setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN); +} + +/* + * Allocate DP-Ram and memory buffers. We need to allocate a transmit and + * receive buffer descriptors from dual port ram, and a character + * buffer area from host mem. If we are allocating for the console we need + * to do it from bootmem + */ +static int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) +{ + int dpmemsz, memsz; + u8 __iomem *dp_mem; + unsigned long dp_offset; + u8 *mem_addr; + dma_addr_t dma_addr = 0; + + pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); + + dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); + dp_offset = cpm_muram_alloc(dpmemsz, 8); + if (IS_ERR_VALUE(dp_offset)) { + pr_err("%s: could not allocate buffer descriptors\n", __func__); + return -ENOMEM; + } + + dp_mem = cpm_muram_addr(dp_offset); + + memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + + L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); + if (IS_ENABLED(CONFIG_CPM1) && is_con) { + /* was hostalloc but changed cause it blows away the */ + /* large tlb mapping when pinning the kernel area */ + mem_addr = (u8 __force *)cpm_muram_addr(cpm_muram_alloc(memsz, 8)); + dma_addr = cpm_muram_dma((void __iomem *)mem_addr); + } else if (is_con) { + mem_addr = kzalloc(memsz, GFP_NOWAIT); + dma_addr = virt_to_bus(mem_addr); + } else { + mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, + GFP_KERNEL); + } + + if (!mem_addr) { + cpm_muram_free(dp_offset); + pr_err("%s: could not allocate coherent memory\n", __func__); + return -ENOMEM; + } + + pinfo->dp_addr = dp_offset; + pinfo->mem_addr = mem_addr; + pinfo->dma_addr = dma_addr; + pinfo->mem_size = memsz; + + pinfo->rx_buf = mem_addr; + pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos + * pinfo->rx_fifosize); + + pinfo->rx_bd_base = (cbd_t __iomem *)dp_mem; + pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; + + return 0; +} + +static void cpm_uart_freebuf(struct uart_cpm_port *pinfo) +{ + dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos * + pinfo->rx_fifosize) + + L1_CACHE_ALIGN(pinfo->tx_nrfifos * + pinfo->tx_fifosize), (void __force *)pinfo->mem_addr, + pinfo->dma_addr); + + cpm_muram_free(pinfo->dp_addr); +} + +/* + * Initialize port. This is called from early_console stuff + * so we have to be careful here ! + */ +static int cpm_uart_request_port(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + int ret; + + pr_debug("CPM uart[%d]:request port\n", port->line); + + if (pinfo->flags & FLAG_CONSOLE) + return 0; + + if (IS_SMC(pinfo)) { + clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); + clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); + } else { + clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); + clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); + } + + ret = cpm_uart_allocbuf(pinfo, 0); + + if (ret) + return ret; + + cpm_uart_initbd(pinfo); + if (IS_SMC(pinfo)) + cpm_uart_init_smc(pinfo); + else + cpm_uart_init_scc(pinfo); + + return 0; +} + +static void cpm_uart_release_port(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + + if (!(pinfo->flags & FLAG_CONSOLE)) + cpm_uart_freebuf(pinfo); +} + +/* + * Configure/autoconfigure the port. + */ +static void cpm_uart_config_port(struct uart_port *port, int flags) +{ + pr_debug("CPM uart[%d]:config_port\n", port->line); + + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_CPM; + cpm_uart_request_port(port); + } +} + +#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) +/* + * Write a string to the serial port + * Note that this is called with interrupts already disabled + */ +static void cpm_uart_early_write(struct uart_cpm_port *pinfo, + const char *string, u_int count, bool handle_linefeed) +{ + unsigned int i; + cbd_t __iomem *bdp, *bdbase; + unsigned char *cpm_outp_addr; + + /* Get the address of the host memory buffer. + */ + bdp = pinfo->tx_cur; + bdbase = pinfo->tx_bd_base; + + /* + * Now, do each character. This is not as bad as it looks + * since this is a holding FIFO and not a transmitting FIFO. + * We could add the complexity of filling the entire transmit + * buffer, but we would just wait longer between accesses...... + */ + for (i = 0; i < count; i++, string++) { + /* Wait for transmitter fifo to empty. + * Ready indicates output is ready, and xmt is doing + * that, not that it is ready for us to send. + */ + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + /* Send the character out. + * If the buffer address is in the CPM DPRAM, don't + * convert it. + */ + cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), + pinfo); + *cpm_outp_addr = *string; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + + /* if a LF, also do CR... */ + if (handle_linefeed && *string == 10) { + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), + pinfo); + *cpm_outp_addr = 13; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + pinfo->tx_cur = bdp; +} +#endif + +#ifdef CONFIG_CONSOLE_POLL +/* Serial polling routines for writing and reading from the uart while + * in an interrupt or debug context. + */ + +#define GDB_BUF_SIZE 512 /* power of 2, please */ + +static char poll_buf[GDB_BUF_SIZE]; +static char *pollp; +static int poll_chars; + +static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo) +{ + u_char c, *cp; + volatile cbd_t *bdp; + int i; + + /* Get the address of the host memory buffer. + */ + bdp = pinfo->rx_cur; + if (bdp->cbd_sc & BD_SC_EMPTY) + return NO_POLL_CHAR; + + /* If the buffer address is in the CPM DPRAM, don't + * convert it. + */ + cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + + if (obuf) { + i = c = bdp->cbd_datlen; + while (i-- > 0) + *obuf++ = *cp++; + } else + c = *cp; + bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID); + bdp->cbd_sc |= BD_SC_EMPTY; + + if (bdp->cbd_sc & BD_SC_WRAP) + bdp = pinfo->rx_bd_base; + else + bdp++; + pinfo->rx_cur = (cbd_t *)bdp; + + return (int)c; +} + +static int cpm_get_poll_char(struct uart_port *port) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + + if (!serial_polled) { + serial_polled = 1; + poll_chars = 0; + } + if (poll_chars <= 0) { + int ret = poll_wait_key(poll_buf, pinfo); + + if (ret == NO_POLL_CHAR) + return ret; + poll_chars = ret; + pollp = poll_buf; + } + poll_chars--; + return *pollp++; +} + +static void cpm_put_poll_char(struct uart_port *port, + unsigned char c) +{ + struct uart_cpm_port *pinfo = + container_of(port, struct uart_cpm_port, port); + static char ch[2]; + + ch[0] = (char)c; + cpm_uart_early_write(pinfo, ch, 1, false); +} + +#ifdef CONFIG_SERIAL_CPM_CONSOLE +static struct uart_port *udbg_port; + +static void udbg_cpm_putc(char c) +{ + if (c == '\n') + cpm_put_poll_char(udbg_port, '\r'); + cpm_put_poll_char(udbg_port, c); +} + +static int udbg_cpm_getc_poll(void) +{ + int c = cpm_get_poll_char(udbg_port); + + return c == NO_POLL_CHAR ? -1 : c; +} + +static int udbg_cpm_getc(void) +{ + int c; + + while ((c = udbg_cpm_getc_poll()) == -1) + cpu_relax(); + return c; +} +#endif /* CONFIG_SERIAL_CPM_CONSOLE */ + +#endif /* CONFIG_CONSOLE_POLL */ + +static const struct uart_ops cpm_uart_pops = { + .tx_empty = cpm_uart_tx_empty, + .set_mctrl = cpm_uart_set_mctrl, + .get_mctrl = cpm_uart_get_mctrl, + .stop_tx = cpm_uart_stop_tx, + .start_tx = cpm_uart_start_tx, + .stop_rx = cpm_uart_stop_rx, + .break_ctl = cpm_uart_break_ctl, + .startup = cpm_uart_startup, + .shutdown = cpm_uart_shutdown, + .set_termios = cpm_uart_set_termios, + .type = cpm_uart_type, + .release_port = cpm_uart_release_port, + .request_port = cpm_uart_request_port, + .config_port = cpm_uart_config_port, + .verify_port = cpm_uart_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = cpm_get_poll_char, + .poll_put_char = cpm_put_poll_char, +#endif +}; + +static struct uart_cpm_port cpm_uart_ports[UART_NR]; + +static void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, + struct device_node *np) +{ + void __iomem *pram; + unsigned long offset; + struct resource res; + resource_size_t len; + + /* Don't remap parameter RAM if it has already been initialized + * during console setup. + */ + if (IS_SMC(port) && port->smcup) + return port->smcup; + else if (!IS_SMC(port) && port->sccup) + return port->sccup; + + if (of_address_to_resource(np, 1, &res)) + return NULL; + + len = resource_size(&res); + pram = ioremap(res.start, len); + if (!pram) + return NULL; + + if (!IS_ENABLED(CONFIG_CPM2) || !IS_SMC(port)) + return pram; + + if (len != 2) { + pr_warn("cpm_uart[%d]: device tree references " + "SMC pram, using boot loader/wrapper pram mapping. " + "Please fix your device tree to reference the pram " + "base register instead.\n", + port->port.line); + return pram; + } + + offset = cpm_muram_alloc(64, 64); + out_be16(pram, offset); + iounmap(pram); + return cpm_muram_addr(offset); +} + +static void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) +{ + if (!IS_ENABLED(CONFIG_CPM2) || !IS_SMC(port)) + iounmap(pram); +} + +static int cpm_uart_init_port(struct device_node *np, + struct uart_cpm_port *pinfo) +{ + const u32 *data; + void __iomem *mem, *pram; + struct device *dev = pinfo->port.dev; + int len; + int ret; + int i; + + data = of_get_property(np, "clock", NULL); + if (data) { + struct clk *clk = clk_get(NULL, (const char*)data); + if (!IS_ERR(clk)) + pinfo->clk = clk; + } + if (!pinfo->clk) { + data = of_get_property(np, "fsl,cpm-brg", &len); + if (!data || len != 4) { + printk(KERN_ERR "CPM UART %pOFn has no/invalid " + "fsl,cpm-brg property.\n", np); + return -EINVAL; + } + pinfo->brg = *data; + } + + data = of_get_property(np, "fsl,cpm-command", &len); + if (!data || len != 4) { + printk(KERN_ERR "CPM UART %pOFn has no/invalid " + "fsl,cpm-command property.\n", np); + return -EINVAL; + } + pinfo->command = *data; + + mem = of_iomap(np, 0); + if (!mem) + return -ENOMEM; + + if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") || + of_device_is_compatible(np, "fsl,cpm2-scc-uart")) { + pinfo->sccp = mem; + pinfo->sccup = pram = cpm_uart_map_pram(pinfo, np); + } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") || + of_device_is_compatible(np, "fsl,cpm2-smc-uart")) { + pinfo->flags |= FLAG_SMC; + pinfo->smcp = mem; + pinfo->smcup = pram = cpm_uart_map_pram(pinfo, np); + } else { + ret = -ENODEV; + goto out_mem; + } + + if (!pram) { + ret = -ENOMEM; + goto out_mem; + } + + pinfo->tx_nrfifos = TX_NUM_FIFO; + pinfo->tx_fifosize = TX_BUF_SIZE; + pinfo->rx_nrfifos = RX_NUM_FIFO; + pinfo->rx_fifosize = RX_BUF_SIZE; + + pinfo->port.uartclk = ppc_proc_freq; + pinfo->port.mapbase = (unsigned long)mem; + pinfo->port.type = PORT_CPM; + pinfo->port.ops = &cpm_uart_pops; + pinfo->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_CPM_CONSOLE); + pinfo->port.iotype = UPIO_MEM; + pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; + spin_lock_init(&pinfo->port.lock); + + for (i = 0; i < NUM_GPIOS; i++) { + struct gpio_desc *gpiod; + + pinfo->gpios[i] = NULL; + + gpiod = devm_gpiod_get_index_optional(dev, NULL, i, GPIOD_ASIS); + + if (IS_ERR(gpiod)) { + ret = PTR_ERR(gpiod); + goto out_pram; + } + + if (gpiod) { + if (i == GPIO_RTS || i == GPIO_DTR) + ret = gpiod_direction_output(gpiod, 0); + else + ret = gpiod_direction_input(gpiod); + if (ret) { + pr_err("can't set direction for gpio #%d: %d\n", + i, ret); + continue; + } + pinfo->gpios[i] = gpiod; + } + } + +#ifdef CONFIG_PPC_EARLY_DEBUG_CPM +#if defined(CONFIG_CONSOLE_POLL) && defined(CONFIG_SERIAL_CPM_CONSOLE) + if (!udbg_port) +#endif + udbg_putc = NULL; +#endif + + return cpm_uart_request_port(&pinfo->port); + +out_pram: + cpm_uart_unmap_pram(pinfo, pram); +out_mem: + iounmap(mem); + return ret; +} + +#ifdef CONFIG_SERIAL_CPM_CONSOLE +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * Note that this is called with interrupts already disabled + */ +static void cpm_uart_console_write(struct console *co, const char *s, + u_int count) +{ + struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; + unsigned long flags; + + if (unlikely(oops_in_progress)) { + local_irq_save(flags); + cpm_uart_early_write(pinfo, s, count, true); + local_irq_restore(flags); + } else { + spin_lock_irqsave(&pinfo->port.lock, flags); + cpm_uart_early_write(pinfo, s, count, true); + spin_unlock_irqrestore(&pinfo->port.lock, flags); + } +} + + +static int __init cpm_uart_console_setup(struct console *co, char *options) +{ + int baud = 38400; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + int ret; + struct uart_cpm_port *pinfo; + struct uart_port *port; + + struct device_node *np; + int i = 0; + + if (co->index >= UART_NR) { + printk(KERN_ERR "cpm_uart: console index %d too high\n", + co->index); + return -ENODEV; + } + + for_each_node_by_type(np, "serial") { + if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") && + !of_device_is_compatible(np, "fsl,cpm1-scc-uart") && + !of_device_is_compatible(np, "fsl,cpm2-smc-uart") && + !of_device_is_compatible(np, "fsl,cpm2-scc-uart")) + continue; + + if (i++ == co->index) + break; + } + + if (!np) + return -ENODEV; + + pinfo = &cpm_uart_ports[co->index]; + + pinfo->flags |= FLAG_CONSOLE; + port = &pinfo->port; + + ret = cpm_uart_init_port(np, pinfo); + of_node_put(np); + if (ret) + return ret; + + if (options) { + uart_parse_options(options, &baud, &parity, &bits, &flow); + } else { + baud = get_baudrate(); + if (baud == -1) + baud = 9600; + } + + if (IS_SMC(pinfo)) { + out_be16(&pinfo->smcup->smc_brkcr, 0); + cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); + clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); + clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); + } else { + out_be16(&pinfo->sccup->scc_brkcr, 0); + cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); + clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); + clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); + } + + ret = cpm_uart_allocbuf(pinfo, 1); + + if (ret) + return ret; + + cpm_uart_initbd(pinfo); + + if (IS_SMC(pinfo)) + cpm_uart_init_smc(pinfo); + else + cpm_uart_init_scc(pinfo); + + uart_set_options(port, co, baud, parity, bits, flow); + cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); + +#ifdef CONFIG_CONSOLE_POLL + if (!udbg_port) { + udbg_port = &pinfo->port; + udbg_putc = udbg_cpm_putc; + udbg_getc = udbg_cpm_getc; + udbg_getc_poll = udbg_cpm_getc_poll; + } +#endif + + return 0; +} + +static struct uart_driver cpm_reg; +static struct console cpm_scc_uart_console = { + .name = "ttyCPM", + .write = cpm_uart_console_write, + .device = uart_console_device, + .setup = cpm_uart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &cpm_reg, +}; + +static int __init cpm_uart_console_init(void) +{ + cpm_muram_init(); + register_console(&cpm_scc_uart_console); + return 0; +} + +console_initcall(cpm_uart_console_init); + +#define CPM_UART_CONSOLE &cpm_scc_uart_console +#else +#define CPM_UART_CONSOLE NULL +#endif + +static struct uart_driver cpm_reg = { + .owner = THIS_MODULE, + .driver_name = "ttyCPM", + .dev_name = "ttyCPM", + .major = SERIAL_CPM_MAJOR, + .minor = SERIAL_CPM_MINOR, + .cons = CPM_UART_CONSOLE, + .nr = UART_NR, +}; + +static int probe_index; + +static int cpm_uart_probe(struct platform_device *ofdev) +{ + int index = probe_index++; + struct uart_cpm_port *pinfo = &cpm_uart_ports[index]; + int ret; + + pinfo->port.line = index; + + if (index >= UART_NR) + return -ENODEV; + + platform_set_drvdata(ofdev, pinfo); + + /* initialize the device pointer for the port */ + pinfo->port.dev = &ofdev->dev; + + pinfo->port.irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); + if (!pinfo->port.irq) + return -EINVAL; + + ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo); + if (!ret) + return uart_add_one_port(&cpm_reg, &pinfo->port); + + irq_dispose_mapping(pinfo->port.irq); + + return ret; +} + +static int cpm_uart_remove(struct platform_device *ofdev) +{ + struct uart_cpm_port *pinfo = platform_get_drvdata(ofdev); + + uart_remove_one_port(&cpm_reg, &pinfo->port); + + return 0; +} + +static const struct of_device_id cpm_uart_match[] = { + { + .compatible = "fsl,cpm1-smc-uart", + }, + { + .compatible = "fsl,cpm1-scc-uart", + }, + { + .compatible = "fsl,cpm2-smc-uart", + }, + { + .compatible = "fsl,cpm2-scc-uart", + }, + {} +}; +MODULE_DEVICE_TABLE(of, cpm_uart_match); + +static struct platform_driver cpm_uart_driver = { + .driver = { + .name = "cpm_uart", + .of_match_table = cpm_uart_match, + }, + .probe = cpm_uart_probe, + .remove = cpm_uart_remove, + }; + +static int __init cpm_uart_init(void) +{ + int ret = uart_register_driver(&cpm_reg); + if (ret) + return ret; + + ret = platform_driver_register(&cpm_uart_driver); + if (ret) + uart_unregister_driver(&cpm_reg); + + return ret; +} + +static void __exit cpm_uart_exit(void) +{ + platform_driver_unregister(&cpm_uart_driver); + uart_unregister_driver(&cpm_reg); +} + +module_init(cpm_uart_init); +module_exit(cpm_uart_exit); + +MODULE_AUTHOR("Kumar Gala/Antoniou Pantelis"); +MODULE_DESCRIPTION("CPM SCC/SMC port driver $Revision: 0.01 $"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV(SERIAL_CPM_MAJOR, SERIAL_CPM_MINOR); diff --git a/drivers/tty/serial/cpm_uart.h b/drivers/tty/serial/cpm_uart.h new file mode 100644 index 000000000000..37bb6e976e03 --- /dev/null +++ b/drivers/tty/serial/cpm_uart.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Driver for CPM (SCC/SMC) serial ports + * + * Copyright (C) 2004 Freescale Semiconductor, Inc. + * + * 2006 (c) MontaVista Software, Inc. + * Vitaly Bordug + */ +#ifndef CPM_UART_H +#define CPM_UART_H + +#include + +struct gpio_desc; + +#if defined(CONFIG_CPM2) +#include "asm/cpm2.h" +#elif defined(CONFIG_CPM1) +#include "asm/cpm1.h" +#endif + +#define DPRAM_BASE ((u8 __iomem *)cpm_muram_addr(0)) + +#define SERIAL_CPM_MAJOR 204 +#define SERIAL_CPM_MINOR 46 + +#define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC) +#define FLAG_SMC 0x00000002 +#define FLAG_CONSOLE 0x00000001 + +#define UART_NR 6 + +#define RX_NUM_FIFO 4 +#define RX_BUF_SIZE 32 +#define TX_NUM_FIFO 4 +#define TX_BUF_SIZE 32 + +#define GPIO_CTS 0 +#define GPIO_RTS 1 +#define GPIO_DCD 2 +#define GPIO_DSR 3 +#define GPIO_DTR 4 +#define GPIO_RI 5 + +#define NUM_GPIOS (GPIO_RI+1) + +struct uart_cpm_port { + struct uart_port port; + u16 rx_nrfifos; + u16 rx_fifosize; + u16 tx_nrfifos; + u16 tx_fifosize; + smc_t __iomem *smcp; + smc_uart_t __iomem *smcup; + scc_t __iomem *sccp; + scc_uart_t __iomem *sccup; + cbd_t __iomem *rx_bd_base; + cbd_t __iomem *rx_cur; + cbd_t __iomem *tx_bd_base; + cbd_t __iomem *tx_cur; + unsigned char *tx_buf; + unsigned char *rx_buf; + u32 flags; + struct clk *clk; + u8 brg; + uint dp_addr; + void *mem_addr; + dma_addr_t dma_addr; + u32 mem_size; + /* wait on close if needed */ + int wait_closing; + /* value to combine with opcode to form cpm command */ + u32 command; + struct gpio_desc *gpios[NUM_GPIOS]; +}; + +/* + virtual to phys transtalion +*/ +static inline unsigned long cpu2cpm_addr(void *addr, + struct uart_cpm_port *pinfo) +{ + int offset; + u32 val = (u32)addr; + u32 mem = (u32)pinfo->mem_addr; + /* sane check */ + if (likely(val >= mem && val < mem + pinfo->mem_size)) { + offset = val - mem; + return pinfo->dma_addr + offset; + } + /* something nasty happened */ + BUG(); + return 0; +} + +static inline void *cpm2cpu_addr(unsigned long addr, + struct uart_cpm_port *pinfo) +{ + int offset; + u32 val = addr; + u32 dma = (u32)pinfo->dma_addr; + /* sane check */ + if (likely(val >= dma && val < dma + pinfo->mem_size)) { + offset = val - dma; + return pinfo->mem_addr + offset; + } + /* something nasty happened */ + BUG(); + return NULL; +} + + +#endif /* CPM_UART_H */ diff --git a/drivers/tty/serial/cpm_uart/Makefile b/drivers/tty/serial/cpm_uart/Makefile deleted file mode 100644 index 91f202fa5251..000000000000 --- a/drivers/tty/serial/cpm_uart/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for the Motorola 8xx FEC ethernet controller -# - -obj-$(CONFIG_SERIAL_CPM) += cpm_uart_core.o diff --git a/drivers/tty/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h deleted file mode 100644 index 37bb6e976e03..000000000000 --- a/drivers/tty/serial/cpm_uart/cpm_uart.h +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Driver for CPM (SCC/SMC) serial ports - * - * Copyright (C) 2004 Freescale Semiconductor, Inc. - * - * 2006 (c) MontaVista Software, Inc. - * Vitaly Bordug - */ -#ifndef CPM_UART_H -#define CPM_UART_H - -#include - -struct gpio_desc; - -#if defined(CONFIG_CPM2) -#include "asm/cpm2.h" -#elif defined(CONFIG_CPM1) -#include "asm/cpm1.h" -#endif - -#define DPRAM_BASE ((u8 __iomem *)cpm_muram_addr(0)) - -#define SERIAL_CPM_MAJOR 204 -#define SERIAL_CPM_MINOR 46 - -#define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC) -#define FLAG_SMC 0x00000002 -#define FLAG_CONSOLE 0x00000001 - -#define UART_NR 6 - -#define RX_NUM_FIFO 4 -#define RX_BUF_SIZE 32 -#define TX_NUM_FIFO 4 -#define TX_BUF_SIZE 32 - -#define GPIO_CTS 0 -#define GPIO_RTS 1 -#define GPIO_DCD 2 -#define GPIO_DSR 3 -#define GPIO_DTR 4 -#define GPIO_RI 5 - -#define NUM_GPIOS (GPIO_RI+1) - -struct uart_cpm_port { - struct uart_port port; - u16 rx_nrfifos; - u16 rx_fifosize; - u16 tx_nrfifos; - u16 tx_fifosize; - smc_t __iomem *smcp; - smc_uart_t __iomem *smcup; - scc_t __iomem *sccp; - scc_uart_t __iomem *sccup; - cbd_t __iomem *rx_bd_base; - cbd_t __iomem *rx_cur; - cbd_t __iomem *tx_bd_base; - cbd_t __iomem *tx_cur; - unsigned char *tx_buf; - unsigned char *rx_buf; - u32 flags; - struct clk *clk; - u8 brg; - uint dp_addr; - void *mem_addr; - dma_addr_t dma_addr; - u32 mem_size; - /* wait on close if needed */ - int wait_closing; - /* value to combine with opcode to form cpm command */ - u32 command; - struct gpio_desc *gpios[NUM_GPIOS]; -}; - -/* - virtual to phys transtalion -*/ -static inline unsigned long cpu2cpm_addr(void *addr, - struct uart_cpm_port *pinfo) -{ - int offset; - u32 val = (u32)addr; - u32 mem = (u32)pinfo->mem_addr; - /* sane check */ - if (likely(val >= mem && val < mem + pinfo->mem_size)) { - offset = val - mem; - return pinfo->dma_addr + offset; - } - /* something nasty happened */ - BUG(); - return 0; -} - -static inline void *cpm2cpu_addr(unsigned long addr, - struct uart_cpm_port *pinfo) -{ - int offset; - u32 val = addr; - u32 dma = (u32)pinfo->dma_addr; - /* sane check */ - if (likely(val >= dma && val < dma + pinfo->mem_size)) { - offset = val - dma; - return pinfo->mem_addr + offset; - } - /* something nasty happened */ - BUG(); - return NULL; -} - - -#endif /* CPM_UART_H */ diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c deleted file mode 100644 index 626423022d62..000000000000 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ /dev/null @@ -1,1612 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for CPM (SCC/SMC) serial ports; core driver - * - * Based on arch/ppc/cpm2_io/uart.c by Dan Malek - * Based on ppc8xx.c by Thomas Gleixner - * Based on drivers/serial/amba.c by Russell King - * - * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) - * Pantelis Antoniou (panto@intracom.gr) (CPM1) - * - * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc. - * (C) 2004 Intracom, S.A. - * (C) 2005-2006 MontaVista Software, Inc. - * Vitaly Bordug - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include "cpm_uart.h" - - -/**************************************************************/ - -static int cpm_uart_tx_pump(struct uart_port *port); -static void cpm_uart_initbd(struct uart_cpm_port *pinfo); - -/**************************************************************/ - -#define HW_BUF_SPD_THRESHOLD 2400 - -static void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) -{ - cpm_command(port->command, cmd); -} - -/* - * Check, if transmit buffers are processed -*/ -static unsigned int cpm_uart_tx_empty(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - cbd_t __iomem *bdp = pinfo->tx_bd_base; - int ret = 0; - - while (1) { - if (in_be16(&bdp->cbd_sc) & BD_SC_READY) - break; - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) { - ret = TIOCSER_TEMT; - break; - } - bdp++; - } - - pr_debug("CPM uart[%d]:tx_empty: %d\n", port->line, ret); - - return ret; -} - -static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - - if (pinfo->gpios[GPIO_RTS]) - gpiod_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS)); - - if (pinfo->gpios[GPIO_DTR]) - gpiod_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR)); -} - -static unsigned int cpm_uart_get_mctrl(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - - if (pinfo->gpios[GPIO_CTS]) { - if (gpiod_get_value(pinfo->gpios[GPIO_CTS])) - mctrl &= ~TIOCM_CTS; - } - - if (pinfo->gpios[GPIO_DSR]) { - if (gpiod_get_value(pinfo->gpios[GPIO_DSR])) - mctrl &= ~TIOCM_DSR; - } - - if (pinfo->gpios[GPIO_DCD]) { - if (gpiod_get_value(pinfo->gpios[GPIO_DCD])) - mctrl &= ~TIOCM_CAR; - } - - if (pinfo->gpios[GPIO_RI]) { - if (!gpiod_get_value(pinfo->gpios[GPIO_RI])) - mctrl |= TIOCM_RNG; - } - - return mctrl; -} - -/* - * Stop transmitter - */ -static void cpm_uart_stop_tx(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - smc_t __iomem *smcp = pinfo->smcp; - scc_t __iomem *sccp = pinfo->sccp; - - pr_debug("CPM uart[%d]:stop tx\n", port->line); - - if (IS_SMC(pinfo)) - clrbits8(&smcp->smc_smcm, SMCM_TX); - else - clrbits16(&sccp->scc_sccm, UART_SCCM_TX); -} - -/* - * Start transmitter - */ -static void cpm_uart_start_tx(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - smc_t __iomem *smcp = pinfo->smcp; - scc_t __iomem *sccp = pinfo->sccp; - - pr_debug("CPM uart[%d]:start tx\n", port->line); - - if (IS_SMC(pinfo)) { - if (in_8(&smcp->smc_smcm) & SMCM_TX) - return; - } else { - if (in_be16(&sccp->scc_sccm) & UART_SCCM_TX) - return; - } - - if (cpm_uart_tx_pump(port) != 0) { - if (IS_SMC(pinfo)) { - setbits8(&smcp->smc_smcm, SMCM_TX); - } else { - setbits16(&sccp->scc_sccm, UART_SCCM_TX); - } - } -} - -/* - * Stop receiver - */ -static void cpm_uart_stop_rx(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - smc_t __iomem *smcp = pinfo->smcp; - scc_t __iomem *sccp = pinfo->sccp; - - pr_debug("CPM uart[%d]:stop rx\n", port->line); - - if (IS_SMC(pinfo)) - clrbits8(&smcp->smc_smcm, SMCM_RX); - else - clrbits16(&sccp->scc_sccm, UART_SCCM_RX); -} - -/* - * Generate a break. - */ -static void cpm_uart_break_ctl(struct uart_port *port, int break_state) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - - pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, - break_state); - - if (break_state) - cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); - else - cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); -} - -/* - * Transmit characters, refill buffer descriptor, if possible - */ -static void cpm_uart_int_tx(struct uart_port *port) -{ - pr_debug("CPM uart[%d]:TX INT\n", port->line); - - cpm_uart_tx_pump(port); -} - -#ifdef CONFIG_CONSOLE_POLL -static int serial_polled; -#endif - -/* - * Receive characters - */ -static void cpm_uart_int_rx(struct uart_port *port) -{ - int i; - unsigned char ch; - u8 *cp; - struct tty_port *tport = &port->state->port; - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - cbd_t __iomem *bdp; - u16 status; - unsigned int flg; - - pr_debug("CPM uart[%d]:RX INT\n", port->line); - - /* Just loop through the closed BDs and copy the characters into - * the buffer. - */ - bdp = pinfo->rx_cur; - for (;;) { -#ifdef CONFIG_CONSOLE_POLL - if (unlikely(serial_polled)) { - serial_polled = 0; - return; - } -#endif - /* get status */ - status = in_be16(&bdp->cbd_sc); - /* If this one is empty, return happy */ - if (status & BD_SC_EMPTY) - break; - - /* get number of characters, and check spce in flip-buffer */ - i = in_be16(&bdp->cbd_datlen); - - /* If we have not enough room in tty flip buffer, then we try - * later, which will be the next rx-interrupt or a timeout - */ - if (tty_buffer_request_room(tport, i) < i) { - printk(KERN_WARNING "No room in flip buffer\n"); - return; - } - - /* get pointer */ - cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); - - /* loop through the buffer */ - while (i-- > 0) { - ch = *cp++; - port->icount.rx++; - flg = TTY_NORMAL; - - if (status & - (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) - goto handle_error; - if (uart_handle_sysrq_char(port, ch)) - continue; -#ifdef CONFIG_CONSOLE_POLL - if (unlikely(serial_polled)) { - serial_polled = 0; - return; - } -#endif - error_return: - tty_insert_flip_char(tport, ch, flg); - - } /* End while (i--) */ - - /* This BD is ready to be used again. Clear status. get next */ - clrbits16(&bdp->cbd_sc, BD_SC_BR | BD_SC_FR | BD_SC_PR | - BD_SC_OV | BD_SC_ID); - setbits16(&bdp->cbd_sc, BD_SC_EMPTY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = pinfo->rx_bd_base; - else - bdp++; - - } /* End for (;;) */ - - /* Write back buffer pointer */ - pinfo->rx_cur = bdp; - - /* activate BH processing */ - tty_flip_buffer_push(tport); - - return; - - /* Error processing */ - - handle_error: - /* Statistics */ - if (status & BD_SC_BR) - port->icount.brk++; - if (status & BD_SC_PR) - port->icount.parity++; - if (status & BD_SC_FR) - port->icount.frame++; - if (status & BD_SC_OV) - port->icount.overrun++; - - /* Mask out ignored conditions */ - status &= port->read_status_mask; - - /* Handle the remaining ones */ - if (status & BD_SC_BR) - flg = TTY_BREAK; - else if (status & BD_SC_PR) - flg = TTY_PARITY; - else if (status & BD_SC_FR) - flg = TTY_FRAME; - - /* overrun does not affect the current character ! */ - if (status & BD_SC_OV) { - ch = 0; - flg = TTY_OVERRUN; - /* We skip this buffer */ - /* CHECK: Is really nothing senseful there */ - /* ASSUMPTION: it contains nothing valid */ - i = 0; - } - port->sysrq = 0; - goto error_return; -} - -/* - * Asynchron mode interrupt handler - */ -static irqreturn_t cpm_uart_int(int irq, void *data) -{ - u8 events; - struct uart_port *port = data; - struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - smc_t __iomem *smcp = pinfo->smcp; - scc_t __iomem *sccp = pinfo->sccp; - - pr_debug("CPM uart[%d]:IRQ\n", port->line); - - if (IS_SMC(pinfo)) { - events = in_8(&smcp->smc_smce); - out_8(&smcp->smc_smce, events); - if (events & SMCM_BRKE) - uart_handle_break(port); - if (events & SMCM_RX) - cpm_uart_int_rx(port); - if (events & SMCM_TX) - cpm_uart_int_tx(port); - } else { - events = in_be16(&sccp->scc_scce); - out_be16(&sccp->scc_scce, events); - if (events & UART_SCCM_BRKE) - uart_handle_break(port); - if (events & UART_SCCM_RX) - cpm_uart_int_rx(port); - if (events & UART_SCCM_TX) - cpm_uart_int_tx(port); - } - return (events) ? IRQ_HANDLED : IRQ_NONE; -} - -static int cpm_uart_startup(struct uart_port *port) -{ - int retval; - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - - pr_debug("CPM uart[%d]:startup\n", port->line); - - /* If the port is not the console, make sure rx is disabled. */ - if (!(pinfo->flags & FLAG_CONSOLE)) { - /* Disable UART rx */ - if (IS_SMC(pinfo)) { - clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN); - clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX); - } else { - clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR); - clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); - } - cpm_uart_initbd(pinfo); - if (IS_SMC(pinfo)) { - out_be32(&pinfo->smcup->smc_rstate, 0); - out_be32(&pinfo->smcup->smc_tstate, 0); - out_be16(&pinfo->smcup->smc_rbptr, - in_be16(&pinfo->smcup->smc_rbase)); - out_be16(&pinfo->smcup->smc_tbptr, - in_be16(&pinfo->smcup->smc_tbase)); - } else { - cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); - } - } - /* Install interrupt handler. */ - retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); - if (retval) - return retval; - - /* Startup rx-int */ - if (IS_SMC(pinfo)) { - setbits8(&pinfo->smcp->smc_smcm, SMCM_RX); - setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN)); - } else { - setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); - setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT)); - } - - return 0; -} - -inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo) -{ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(pinfo->wait_closing); -} - -/* - * Shutdown the uart - */ -static void cpm_uart_shutdown(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - - pr_debug("CPM uart[%d]:shutdown\n", port->line); - - /* free interrupt handler */ - free_irq(port->irq, port); - - /* If the port is not the console, disable Rx and Tx. */ - if (!(pinfo->flags & FLAG_CONSOLE)) { - /* Wait for all the BDs marked sent */ - while(!cpm_uart_tx_empty(port)) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(2); - } - - if (pinfo->wait_closing) - cpm_uart_wait_until_send(pinfo); - - /* Stop uarts */ - if (IS_SMC(pinfo)) { - smc_t __iomem *smcp = pinfo->smcp; - clrbits16(&smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); - clrbits8(&smcp->smc_smcm, SMCM_RX | SMCM_TX); - } else { - scc_t __iomem *sccp = pinfo->sccp; - clrbits32(&sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); - clrbits16(&sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); - } - - /* Shut them really down and reinit buffer descriptors */ - if (IS_SMC(pinfo)) { - out_be16(&pinfo->smcup->smc_brkcr, 0); - cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); - } else { - out_be16(&pinfo->sccup->scc_brkcr, 0); - cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); - } - - cpm_uart_initbd(pinfo); - } -} - -static void cpm_uart_set_termios(struct uart_port *port, - struct ktermios *termios, - const struct ktermios *old) -{ - int baud; - unsigned long flags; - u16 cval, scval, prev_mode; - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - smc_t __iomem *smcp = pinfo->smcp; - scc_t __iomem *sccp = pinfo->sccp; - int maxidl; - - pr_debug("CPM uart[%d]:set_termios\n", port->line); - - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); - if (baud < HW_BUF_SPD_THRESHOLD || port->flags & UPF_LOW_LATENCY) - pinfo->rx_fifosize = 1; - else - pinfo->rx_fifosize = RX_BUF_SIZE; - - /* MAXIDL is the timeout after which a receive buffer is closed - * when not full if no more characters are received. - * We calculate it from the baudrate so that the duration is - * always the same at standard rates: about 4ms. - */ - maxidl = baud / 2400; - if (maxidl < 1) - maxidl = 1; - if (maxidl > 0x10) - maxidl = 0x10; - - cval = 0; - scval = 0; - - if (termios->c_cflag & CSTOPB) { - cval |= SMCMR_SL; /* Two stops */ - scval |= SCU_PSMR_SL; - } - - if (termios->c_cflag & PARENB) { - cval |= SMCMR_PEN; - scval |= SCU_PSMR_PEN; - if (!(termios->c_cflag & PARODD)) { - cval |= SMCMR_PM_EVEN; - scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP); - } - } - - /* - * Update the timeout - */ - uart_update_timeout(port, termios->c_cflag, baud); - - /* - * Set up parity check flag - */ - port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); - if (termios->c_iflag & INPCK) - port->read_status_mask |= BD_SC_FR | BD_SC_PR; - if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK)) - port->read_status_mask |= BD_SC_BR; - - /* - * Characters to ignore - */ - port->ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; - if (termios->c_iflag & IGNBRK) { - port->ignore_status_mask |= BD_SC_BR; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= BD_SC_OV; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((termios->c_cflag & CREAD) == 0) - port->read_status_mask &= ~BD_SC_EMPTY; - - spin_lock_irqsave(&port->lock, flags); - - if (IS_SMC(pinfo)) { - unsigned int bits = tty_get_frame_size(termios->c_cflag); - - /* - * MRBLR can be changed while an SMC/SCC is operating only - * if it is done in a single bus cycle with one 16-bit move - * (not two 8-bit bus cycles back-to-back). This occurs when - * the cp shifts control to the next RxBD, so the change does - * not take effect immediately. To guarantee the exact RxBD - * on which the change occurs, change MRBLR only while the - * SMC/SCC receiver is disabled. - */ - out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize); - out_be16(&pinfo->smcup->smc_maxidl, maxidl); - - /* Set the mode register. We want to keep a copy of the - * enables, because we want to put them back if they were - * present. - */ - prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN); - /* Output in *one* operation, so we don't interrupt RX/TX if they - * were already enabled. - * Character length programmed into the register is frame bits minus 1. - */ - out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits - 1) | cval | - SMCMR_SM_UART | prev_mode); - } else { - unsigned int bits = tty_get_char_size(termios->c_cflag); - - out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); - out_be16(&pinfo->sccup->scc_maxidl, maxidl); - out_be16(&sccp->scc_psmr, (UART_LCR_WLEN(bits) << 12) | scval); - } - - if (pinfo->clk) - clk_set_rate(pinfo->clk, baud); - else - cpm_setbrg(pinfo->brg - 1, baud); - spin_unlock_irqrestore(&port->lock, flags); -} - -static const char *cpm_uart_type(struct uart_port *port) -{ - pr_debug("CPM uart[%d]:uart_type\n", port->line); - - return port->type == PORT_CPM ? "CPM UART" : NULL; -} - -/* - * verify the new serial_struct (for TIOCSSERIAL). - */ -static int cpm_uart_verify_port(struct uart_port *port, - struct serial_struct *ser) -{ - int ret = 0; - - pr_debug("CPM uart[%d]:verify_port\n", port->line); - - if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) - ret = -EINVAL; - if (ser->irq < 0 || ser->irq >= nr_irqs) - ret = -EINVAL; - if (ser->baud_base < 9600) - ret = -EINVAL; - return ret; -} - -/* - * Transmit characters, refill buffer descriptor, if possible - */ -static int cpm_uart_tx_pump(struct uart_port *port) -{ - cbd_t __iomem *bdp; - u8 *p; - int count; - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - struct circ_buf *xmit = &port->state->xmit; - - /* Handle xon/xoff */ - if (port->x_char) { - /* Pick next descriptor and fill from buffer */ - bdp = pinfo->tx_cur; - - p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); - - *p++ = port->x_char; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - /* Get next BD. */ - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = pinfo->tx_bd_base; - else - bdp++; - pinfo->tx_cur = bdp; - - port->icount.tx++; - port->x_char = 0; - return 1; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - cpm_uart_stop_tx(port); - return 0; - } - - /* Pick next descriptor and fill from buffer */ - bdp = pinfo->tx_cur; - - while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && !uart_circ_empty(xmit)) { - count = 0; - p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); - while (count < pinfo->tx_fifosize) { - *p++ = xmit->buf[xmit->tail]; - uart_xmit_advance(port, 1); - count++; - if (uart_circ_empty(xmit)) - break; - } - out_be16(&bdp->cbd_datlen, count); - setbits16(&bdp->cbd_sc, BD_SC_READY); - /* Get next BD. */ - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = pinfo->tx_bd_base; - else - bdp++; - } - pinfo->tx_cur = bdp; - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) { - cpm_uart_stop_tx(port); - return 0; - } - - return 1; -} - -/* - * init buffer descriptors - */ -static void cpm_uart_initbd(struct uart_cpm_port *pinfo) -{ - int i; - u8 *mem_addr; - cbd_t __iomem *bdp; - - pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line); - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - mem_addr = pinfo->mem_addr; - bdp = pinfo->rx_cur = pinfo->rx_bd_base; - for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { - out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); - out_be16(&bdp->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT); - mem_addr += pinfo->rx_fifosize; - } - - out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); - out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT); - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); - bdp = pinfo->tx_cur = pinfo->tx_bd_base; - for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { - out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); - out_be16(&bdp->cbd_sc, BD_SC_INTRPT); - mem_addr += pinfo->tx_fifosize; - } - - out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); - out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_INTRPT); -} - -static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) -{ - scc_t __iomem *scp; - scc_uart_t __iomem *sup; - - pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line); - - scp = pinfo->sccp; - sup = pinfo->sccup; - - /* Store address */ - out_be16(&pinfo->sccup->scc_genscc.scc_rbase, - (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); - out_be16(&pinfo->sccup->scc_genscc.scc_tbase, - (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); - - /* Set up the uart parameters in the - * parameter ram. - */ - - out_8(&sup->scc_genscc.scc_rfcr, CPMFCR_GBL | CPMFCR_EB); - out_8(&sup->scc_genscc.scc_tfcr, CPMFCR_GBL | CPMFCR_EB); - - out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); - out_be16(&sup->scc_maxidl, 0x10); - out_be16(&sup->scc_brkcr, 1); - out_be16(&sup->scc_parec, 0); - out_be16(&sup->scc_frmec, 0); - out_be16(&sup->scc_nosec, 0); - out_be16(&sup->scc_brkec, 0); - out_be16(&sup->scc_uaddr1, 0); - out_be16(&sup->scc_uaddr2, 0); - out_be16(&sup->scc_toseq, 0); - out_be16(&sup->scc_char1, 0x8000); - out_be16(&sup->scc_char2, 0x8000); - out_be16(&sup->scc_char3, 0x8000); - out_be16(&sup->scc_char4, 0x8000); - out_be16(&sup->scc_char5, 0x8000); - out_be16(&sup->scc_char6, 0x8000); - out_be16(&sup->scc_char7, 0x8000); - out_be16(&sup->scc_char8, 0x8000); - out_be16(&sup->scc_rccm, 0xc0ff); - - /* Send the CPM an initialize command. - */ - cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - out_be32(&scp->scc_gsmrh, 0); - out_be32(&scp->scc_gsmrl, - SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - - /* Enable rx interrupts and clear all pending events. */ - out_be16(&scp->scc_sccm, 0); - out_be16(&scp->scc_scce, 0xffff); - out_be16(&scp->scc_dsr, 0x7e7e); - out_be16(&scp->scc_psmr, 0x3000); - - setbits32(&scp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); -} - -static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) -{ - smc_t __iomem *sp; - smc_uart_t __iomem *up; - - pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); - - sp = pinfo->smcp; - up = pinfo->smcup; - - /* Store address */ - out_be16(&pinfo->smcup->smc_rbase, - (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); - out_be16(&pinfo->smcup->smc_tbase, - (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); - -/* - * In case SMC is being relocated... - */ - out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase)); - out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase)); - out_be32(&up->smc_rstate, 0); - out_be32(&up->smc_tstate, 0); - out_be16(&up->smc_brkcr, 1); /* number of break chars */ - out_be16(&up->smc_brkec, 0); - - /* Set up the uart parameters in the - * parameter ram. - */ - out_8(&up->smc_rfcr, CPMFCR_GBL | CPMFCR_EB); - out_8(&up->smc_tfcr, CPMFCR_GBL | CPMFCR_EB); - - /* Using idle character time requires some additional tuning. */ - out_be16(&up->smc_mrblr, pinfo->rx_fifosize); - out_be16(&up->smc_maxidl, 0x10); - out_be16(&up->smc_brklen, 0); - out_be16(&up->smc_brkec, 0); - out_be16(&up->smc_brkcr, 1); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART); - - /* Enable only rx interrupts clear all pending events. */ - out_8(&sp->smc_smcm, 0); - out_8(&sp->smc_smce, 0xff); - - setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN); -} - -/* - * Allocate DP-Ram and memory buffers. We need to allocate a transmit and - * receive buffer descriptors from dual port ram, and a character - * buffer area from host mem. If we are allocating for the console we need - * to do it from bootmem - */ -static int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) -{ - int dpmemsz, memsz; - u8 __iomem *dp_mem; - unsigned long dp_offset; - u8 *mem_addr; - dma_addr_t dma_addr = 0; - - pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line); - - dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos); - dp_offset = cpm_muram_alloc(dpmemsz, 8); - if (IS_ERR_VALUE(dp_offset)) { - pr_err("%s: could not allocate buffer descriptors\n", __func__); - return -ENOMEM; - } - - dp_mem = cpm_muram_addr(dp_offset); - - memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + - L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); - if (IS_ENABLED(CONFIG_CPM1) && is_con) { - /* was hostalloc but changed cause it blows away the */ - /* large tlb mapping when pinning the kernel area */ - mem_addr = (u8 __force *)cpm_muram_addr(cpm_muram_alloc(memsz, 8)); - dma_addr = cpm_muram_dma((void __iomem *)mem_addr); - } else if (is_con) { - mem_addr = kzalloc(memsz, GFP_NOWAIT); - dma_addr = virt_to_bus(mem_addr); - } else { - mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr, - GFP_KERNEL); - } - - if (!mem_addr) { - cpm_muram_free(dp_offset); - pr_err("%s: could not allocate coherent memory\n", __func__); - return -ENOMEM; - } - - pinfo->dp_addr = dp_offset; - pinfo->mem_addr = mem_addr; - pinfo->dma_addr = dma_addr; - pinfo->mem_size = memsz; - - pinfo->rx_buf = mem_addr; - pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos - * pinfo->rx_fifosize); - - pinfo->rx_bd_base = (cbd_t __iomem *)dp_mem; - pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; - - return 0; -} - -static void cpm_uart_freebuf(struct uart_cpm_port *pinfo) -{ - dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos * - pinfo->rx_fifosize) + - L1_CACHE_ALIGN(pinfo->tx_nrfifos * - pinfo->tx_fifosize), (void __force *)pinfo->mem_addr, - pinfo->dma_addr); - - cpm_muram_free(pinfo->dp_addr); -} - -/* - * Initialize port. This is called from early_console stuff - * so we have to be careful here ! - */ -static int cpm_uart_request_port(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - int ret; - - pr_debug("CPM uart[%d]:request port\n", port->line); - - if (pinfo->flags & FLAG_CONSOLE) - return 0; - - if (IS_SMC(pinfo)) { - clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); - clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); - } else { - clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); - clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); - } - - ret = cpm_uart_allocbuf(pinfo, 0); - - if (ret) - return ret; - - cpm_uart_initbd(pinfo); - if (IS_SMC(pinfo)) - cpm_uart_init_smc(pinfo); - else - cpm_uart_init_scc(pinfo); - - return 0; -} - -static void cpm_uart_release_port(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - - if (!(pinfo->flags & FLAG_CONSOLE)) - cpm_uart_freebuf(pinfo); -} - -/* - * Configure/autoconfigure the port. - */ -static void cpm_uart_config_port(struct uart_port *port, int flags) -{ - pr_debug("CPM uart[%d]:config_port\n", port->line); - - if (flags & UART_CONFIG_TYPE) { - port->type = PORT_CPM; - cpm_uart_request_port(port); - } -} - -#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) -/* - * Write a string to the serial port - * Note that this is called with interrupts already disabled - */ -static void cpm_uart_early_write(struct uart_cpm_port *pinfo, - const char *string, u_int count, bool handle_linefeed) -{ - unsigned int i; - cbd_t __iomem *bdp, *bdbase; - unsigned char *cpm_outp_addr; - - /* Get the address of the host memory buffer. - */ - bdp = pinfo->tx_cur; - bdbase = pinfo->tx_bd_base; - - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, string++) { - /* Wait for transmitter fifo to empty. - * Ready indicates output is ready, and xmt is doing - * that, not that it is ready for us to send. - */ - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - /* Send the character out. - * If the buffer address is in the CPM DPRAM, don't - * convert it. - */ - cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), - pinfo); - *cpm_outp_addr = *string; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (handle_linefeed && *string == 10) { - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), - pinfo); - *cpm_outp_addr = 13; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - pinfo->tx_cur = bdp; -} -#endif - -#ifdef CONFIG_CONSOLE_POLL -/* Serial polling routines for writing and reading from the uart while - * in an interrupt or debug context. - */ - -#define GDB_BUF_SIZE 512 /* power of 2, please */ - -static char poll_buf[GDB_BUF_SIZE]; -static char *pollp; -static int poll_chars; - -static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo) -{ - u_char c, *cp; - volatile cbd_t *bdp; - int i; - - /* Get the address of the host memory buffer. - */ - bdp = pinfo->rx_cur; - if (bdp->cbd_sc & BD_SC_EMPTY) - return NO_POLL_CHAR; - - /* If the buffer address is in the CPM DPRAM, don't - * convert it. - */ - cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); - - if (obuf) { - i = c = bdp->cbd_datlen; - while (i-- > 0) - *obuf++ = *cp++; - } else - c = *cp; - bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID); - bdp->cbd_sc |= BD_SC_EMPTY; - - if (bdp->cbd_sc & BD_SC_WRAP) - bdp = pinfo->rx_bd_base; - else - bdp++; - pinfo->rx_cur = (cbd_t *)bdp; - - return (int)c; -} - -static int cpm_get_poll_char(struct uart_port *port) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - - if (!serial_polled) { - serial_polled = 1; - poll_chars = 0; - } - if (poll_chars <= 0) { - int ret = poll_wait_key(poll_buf, pinfo); - - if (ret == NO_POLL_CHAR) - return ret; - poll_chars = ret; - pollp = poll_buf; - } - poll_chars--; - return *pollp++; -} - -static void cpm_put_poll_char(struct uart_port *port, - unsigned char c) -{ - struct uart_cpm_port *pinfo = - container_of(port, struct uart_cpm_port, port); - static char ch[2]; - - ch[0] = (char)c; - cpm_uart_early_write(pinfo, ch, 1, false); -} - -#ifdef CONFIG_SERIAL_CPM_CONSOLE -static struct uart_port *udbg_port; - -static void udbg_cpm_putc(char c) -{ - if (c == '\n') - cpm_put_poll_char(udbg_port, '\r'); - cpm_put_poll_char(udbg_port, c); -} - -static int udbg_cpm_getc_poll(void) -{ - int c = cpm_get_poll_char(udbg_port); - - return c == NO_POLL_CHAR ? -1 : c; -} - -static int udbg_cpm_getc(void) -{ - int c; - - while ((c = udbg_cpm_getc_poll()) == -1) - cpu_relax(); - return c; -} -#endif /* CONFIG_SERIAL_CPM_CONSOLE */ - -#endif /* CONFIG_CONSOLE_POLL */ - -static const struct uart_ops cpm_uart_pops = { - .tx_empty = cpm_uart_tx_empty, - .set_mctrl = cpm_uart_set_mctrl, - .get_mctrl = cpm_uart_get_mctrl, - .stop_tx = cpm_uart_stop_tx, - .start_tx = cpm_uart_start_tx, - .stop_rx = cpm_uart_stop_rx, - .break_ctl = cpm_uart_break_ctl, - .startup = cpm_uart_startup, - .shutdown = cpm_uart_shutdown, - .set_termios = cpm_uart_set_termios, - .type = cpm_uart_type, - .release_port = cpm_uart_release_port, - .request_port = cpm_uart_request_port, - .config_port = cpm_uart_config_port, - .verify_port = cpm_uart_verify_port, -#ifdef CONFIG_CONSOLE_POLL - .poll_get_char = cpm_get_poll_char, - .poll_put_char = cpm_put_poll_char, -#endif -}; - -static struct uart_cpm_port cpm_uart_ports[UART_NR]; - -static void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, - struct device_node *np) -{ - void __iomem *pram; - unsigned long offset; - struct resource res; - resource_size_t len; - - /* Don't remap parameter RAM if it has already been initialized - * during console setup. - */ - if (IS_SMC(port) && port->smcup) - return port->smcup; - else if (!IS_SMC(port) && port->sccup) - return port->sccup; - - if (of_address_to_resource(np, 1, &res)) - return NULL; - - len = resource_size(&res); - pram = ioremap(res.start, len); - if (!pram) - return NULL; - - if (!IS_ENABLED(CONFIG_CPM2) || !IS_SMC(port)) - return pram; - - if (len != 2) { - pr_warn("cpm_uart[%d]: device tree references " - "SMC pram, using boot loader/wrapper pram mapping. " - "Please fix your device tree to reference the pram " - "base register instead.\n", - port->port.line); - return pram; - } - - offset = cpm_muram_alloc(64, 64); - out_be16(pram, offset); - iounmap(pram); - return cpm_muram_addr(offset); -} - -static void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram) -{ - if (!IS_ENABLED(CONFIG_CPM2) || !IS_SMC(port)) - iounmap(pram); -} - -static int cpm_uart_init_port(struct device_node *np, - struct uart_cpm_port *pinfo) -{ - const u32 *data; - void __iomem *mem, *pram; - struct device *dev = pinfo->port.dev; - int len; - int ret; - int i; - - data = of_get_property(np, "clock", NULL); - if (data) { - struct clk *clk = clk_get(NULL, (const char*)data); - if (!IS_ERR(clk)) - pinfo->clk = clk; - } - if (!pinfo->clk) { - data = of_get_property(np, "fsl,cpm-brg", &len); - if (!data || len != 4) { - printk(KERN_ERR "CPM UART %pOFn has no/invalid " - "fsl,cpm-brg property.\n", np); - return -EINVAL; - } - pinfo->brg = *data; - } - - data = of_get_property(np, "fsl,cpm-command", &len); - if (!data || len != 4) { - printk(KERN_ERR "CPM UART %pOFn has no/invalid " - "fsl,cpm-command property.\n", np); - return -EINVAL; - } - pinfo->command = *data; - - mem = of_iomap(np, 0); - if (!mem) - return -ENOMEM; - - if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") || - of_device_is_compatible(np, "fsl,cpm2-scc-uart")) { - pinfo->sccp = mem; - pinfo->sccup = pram = cpm_uart_map_pram(pinfo, np); - } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") || - of_device_is_compatible(np, "fsl,cpm2-smc-uart")) { - pinfo->flags |= FLAG_SMC; - pinfo->smcp = mem; - pinfo->smcup = pram = cpm_uart_map_pram(pinfo, np); - } else { - ret = -ENODEV; - goto out_mem; - } - - if (!pram) { - ret = -ENOMEM; - goto out_mem; - } - - pinfo->tx_nrfifos = TX_NUM_FIFO; - pinfo->tx_fifosize = TX_BUF_SIZE; - pinfo->rx_nrfifos = RX_NUM_FIFO; - pinfo->rx_fifosize = RX_BUF_SIZE; - - pinfo->port.uartclk = ppc_proc_freq; - pinfo->port.mapbase = (unsigned long)mem; - pinfo->port.type = PORT_CPM; - pinfo->port.ops = &cpm_uart_pops; - pinfo->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_CPM_CONSOLE); - pinfo->port.iotype = UPIO_MEM; - pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; - spin_lock_init(&pinfo->port.lock); - - for (i = 0; i < NUM_GPIOS; i++) { - struct gpio_desc *gpiod; - - pinfo->gpios[i] = NULL; - - gpiod = devm_gpiod_get_index_optional(dev, NULL, i, GPIOD_ASIS); - - if (IS_ERR(gpiod)) { - ret = PTR_ERR(gpiod); - goto out_pram; - } - - if (gpiod) { - if (i == GPIO_RTS || i == GPIO_DTR) - ret = gpiod_direction_output(gpiod, 0); - else - ret = gpiod_direction_input(gpiod); - if (ret) { - pr_err("can't set direction for gpio #%d: %d\n", - i, ret); - continue; - } - pinfo->gpios[i] = gpiod; - } - } - -#ifdef CONFIG_PPC_EARLY_DEBUG_CPM -#if defined(CONFIG_CONSOLE_POLL) && defined(CONFIG_SERIAL_CPM_CONSOLE) - if (!udbg_port) -#endif - udbg_putc = NULL; -#endif - - return cpm_uart_request_port(&pinfo->port); - -out_pram: - cpm_uart_unmap_pram(pinfo, pram); -out_mem: - iounmap(mem); - return ret; -} - -#ifdef CONFIG_SERIAL_CPM_CONSOLE -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * Note that this is called with interrupts already disabled - */ -static void cpm_uart_console_write(struct console *co, const char *s, - u_int count) -{ - struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; - unsigned long flags; - - if (unlikely(oops_in_progress)) { - local_irq_save(flags); - cpm_uart_early_write(pinfo, s, count, true); - local_irq_restore(flags); - } else { - spin_lock_irqsave(&pinfo->port.lock, flags); - cpm_uart_early_write(pinfo, s, count, true); - spin_unlock_irqrestore(&pinfo->port.lock, flags); - } -} - - -static int __init cpm_uart_console_setup(struct console *co, char *options) -{ - int baud = 38400; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - int ret; - struct uart_cpm_port *pinfo; - struct uart_port *port; - - struct device_node *np; - int i = 0; - - if (co->index >= UART_NR) { - printk(KERN_ERR "cpm_uart: console index %d too high\n", - co->index); - return -ENODEV; - } - - for_each_node_by_type(np, "serial") { - if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") && - !of_device_is_compatible(np, "fsl,cpm1-scc-uart") && - !of_device_is_compatible(np, "fsl,cpm2-smc-uart") && - !of_device_is_compatible(np, "fsl,cpm2-scc-uart")) - continue; - - if (i++ == co->index) - break; - } - - if (!np) - return -ENODEV; - - pinfo = &cpm_uart_ports[co->index]; - - pinfo->flags |= FLAG_CONSOLE; - port = &pinfo->port; - - ret = cpm_uart_init_port(np, pinfo); - of_node_put(np); - if (ret) - return ret; - - if (options) { - uart_parse_options(options, &baud, &parity, &bits, &flow); - } else { - baud = get_baudrate(); - if (baud == -1) - baud = 9600; - } - - if (IS_SMC(pinfo)) { - out_be16(&pinfo->smcup->smc_brkcr, 0); - cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); - clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); - clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); - } else { - out_be16(&pinfo->sccup->scc_brkcr, 0); - cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); - clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); - clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); - } - - ret = cpm_uart_allocbuf(pinfo, 1); - - if (ret) - return ret; - - cpm_uart_initbd(pinfo); - - if (IS_SMC(pinfo)) - cpm_uart_init_smc(pinfo); - else - cpm_uart_init_scc(pinfo); - - uart_set_options(port, co, baud, parity, bits, flow); - cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); - -#ifdef CONFIG_CONSOLE_POLL - if (!udbg_port) { - udbg_port = &pinfo->port; - udbg_putc = udbg_cpm_putc; - udbg_getc = udbg_cpm_getc; - udbg_getc_poll = udbg_cpm_getc_poll; - } -#endif - - return 0; -} - -static struct uart_driver cpm_reg; -static struct console cpm_scc_uart_console = { - .name = "ttyCPM", - .write = cpm_uart_console_write, - .device = uart_console_device, - .setup = cpm_uart_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &cpm_reg, -}; - -static int __init cpm_uart_console_init(void) -{ - cpm_muram_init(); - register_console(&cpm_scc_uart_console); - return 0; -} - -console_initcall(cpm_uart_console_init); - -#define CPM_UART_CONSOLE &cpm_scc_uart_console -#else -#define CPM_UART_CONSOLE NULL -#endif - -static struct uart_driver cpm_reg = { - .owner = THIS_MODULE, - .driver_name = "ttyCPM", - .dev_name = "ttyCPM", - .major = SERIAL_CPM_MAJOR, - .minor = SERIAL_CPM_MINOR, - .cons = CPM_UART_CONSOLE, - .nr = UART_NR, -}; - -static int probe_index; - -static int cpm_uart_probe(struct platform_device *ofdev) -{ - int index = probe_index++; - struct uart_cpm_port *pinfo = &cpm_uart_ports[index]; - int ret; - - pinfo->port.line = index; - - if (index >= UART_NR) - return -ENODEV; - - platform_set_drvdata(ofdev, pinfo); - - /* initialize the device pointer for the port */ - pinfo->port.dev = &ofdev->dev; - - pinfo->port.irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); - if (!pinfo->port.irq) - return -EINVAL; - - ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo); - if (!ret) - return uart_add_one_port(&cpm_reg, &pinfo->port); - - irq_dispose_mapping(pinfo->port.irq); - - return ret; -} - -static int cpm_uart_remove(struct platform_device *ofdev) -{ - struct uart_cpm_port *pinfo = platform_get_drvdata(ofdev); - - uart_remove_one_port(&cpm_reg, &pinfo->port); - - return 0; -} - -static const struct of_device_id cpm_uart_match[] = { - { - .compatible = "fsl,cpm1-smc-uart", - }, - { - .compatible = "fsl,cpm1-scc-uart", - }, - { - .compatible = "fsl,cpm2-smc-uart", - }, - { - .compatible = "fsl,cpm2-scc-uart", - }, - {} -}; -MODULE_DEVICE_TABLE(of, cpm_uart_match); - -static struct platform_driver cpm_uart_driver = { - .driver = { - .name = "cpm_uart", - .of_match_table = cpm_uart_match, - }, - .probe = cpm_uart_probe, - .remove = cpm_uart_remove, - }; - -static int __init cpm_uart_init(void) -{ - int ret = uart_register_driver(&cpm_reg); - if (ret) - return ret; - - ret = platform_driver_register(&cpm_uart_driver); - if (ret) - uart_unregister_driver(&cpm_reg); - - return ret; -} - -static void __exit cpm_uart_exit(void) -{ - platform_driver_unregister(&cpm_uart_driver); - uart_unregister_driver(&cpm_reg); -} - -module_init(cpm_uart_init); -module_exit(cpm_uart_exit); - -MODULE_AUTHOR("Kumar Gala/Antoniou Pantelis"); -MODULE_DESCRIPTION("CPM SCC/SMC port driver $Revision: 0.01 $"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV(SERIAL_CPM_MAJOR, SERIAL_CPM_MINOR); -- cgit v1.2.3 From 80a8f487b9bab0d25536516e75f22c78fa657ff4 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:51 +0200 Subject: serial: cpm_uart: Remove stale prototype in powerpc/fsl_soc.c Commit 0b5cf10691eb ("[POWERPC] 8xx: Convert mpc866ads to the new device binding.") removed last definition of init_smc_ioports(). Remove it. And don't include anymore fs_uart_pd.h which is only included to provide fs_uart_platform_info structure. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/2869659e7faa20b0a506347bc4d1059e22709f19.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/sysdev/fsl_soc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 68709743450e..99fc4c3b94fa 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -39,7 +38,6 @@ extern void init_fcc_ioports(struct fs_platform_info*); extern void init_fec_ioports(struct fs_platform_info*); -extern void init_smc_ioports(struct fs_uart_platform_info*); static phys_addr_t immrbase = -1; phys_addr_t get_immrbase(void) -- cgit v1.2.3 From a833b201d90880f65ac04a1518645005e8c78aae Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:52 +0200 Subject: serial: cpm_uart: Don't include fs_uart_pd.h when not needed Remove inclusion of fs_uart_pd.h from all files not using anything from that file. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/c7996ef4de56e7ee42a434e37d214cba337a146c.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/platforms/8xx/mpc885ads_setup.c | 1 - arch/powerpc/platforms/8xx/tqm8xx_setup.c | 1 - drivers/tty/serial/ucc_uart.c | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c index 2fc7cacbcd96..6ecc7fa2a816 100644 --- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c +++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/8xx/tqm8xx_setup.c b/arch/powerpc/platforms/8xx/tqm8xx_setup.c index 7d8eb50bb9cd..a451f5003abd 100644 --- a/arch/powerpc/platforms/8xx/tqm8xx_setup.c +++ b/arch/powerpc/platforms/8xx/tqm8xx_setup.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 49457be37b3f..b06661b80f41 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -29,7 +29,6 @@ #include #include -#include #include #include -- cgit v1.2.3 From a10b6a03e6377f8e658ee3c9f4bc0feae30f3df2 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 3 Aug 2023 15:56:53 +0200 Subject: serial: cpm_uart: Remove linux/fs_uart_pd.h linux/fs_uart_pd.h is not used anymore. Remove it. Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/f2cb444fa2b5776c9c51b5e46ea85edab62d1524.1691068700.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- include/linux/fs_uart_pd.h | 71 ---------------------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 include/linux/fs_uart_pd.h diff --git a/include/linux/fs_uart_pd.h b/include/linux/fs_uart_pd.h deleted file mode 100644 index 36b61ff39277..000000000000 --- a/include/linux/fs_uart_pd.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Platform information definitions for the CPM Uart driver. - * - * 2006 (c) MontaVista Software, Inc. - * Vitaly Bordug - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#ifndef FS_UART_PD_H -#define FS_UART_PD_H - -#include - -enum fs_uart_id { - fsid_smc1_uart, - fsid_smc2_uart, - fsid_scc1_uart, - fsid_scc2_uart, - fsid_scc3_uart, - fsid_scc4_uart, - fs_uart_nr, -}; - -static inline int fs_uart_id_scc2fsid(int id) -{ - return fsid_scc1_uart + id - 1; -} - -static inline int fs_uart_id_fsid2scc(int id) -{ - return id - fsid_scc1_uart + 1; -} - -static inline int fs_uart_id_smc2fsid(int id) -{ - return fsid_smc1_uart + id - 1; -} - -static inline int fs_uart_id_fsid2smc(int id) -{ - return id - fsid_smc1_uart + 1; -} - -struct fs_uart_platform_info { - void(*init_ioports)(struct fs_uart_platform_info *); - /* device specific information */ - int fs_no; /* controller index */ - char fs_type[4]; /* controller type */ - u32 uart_clk; - u8 tx_num_fifo; - u8 tx_buf_size; - u8 rx_num_fifo; - u8 rx_buf_size; - u8 brg; - u8 clk_rx; - u8 clk_tx; -}; - -static inline int fs_uart_get_id(struct fs_uart_platform_info *fpi) -{ - if(strstr(fpi->fs_type, "SMC")) - return fs_uart_id_smc2fsid(fpi->fs_no); - if(strstr(fpi->fs_type, "SCC")) - return fs_uart_id_scc2fsid(fpi->fs_no); - return fpi->fs_no; -} - -#endif -- cgit v1.2.3 From 593135f09368dbddc0244b859a7c3befb97214e0 Mon Sep 17 00:00:00 2001 From: "Sanjuán García, Jorge" Date: Thu, 3 Aug 2023 09:59:07 +0000 Subject: 8250_men_mcb: remove unnecessary cast when reading register Fixes following sparse warning: drivers/tty/serial/8250/8250_men_mcb.c:92:21: sparse: cast removes address space '__iomem' of expression drivers/tty/serial/8250/8250_men_mcb.c:92:21: sparse: incorrect type in argument 1 (different address spaces) expected void const volatile [noderef] __iomem *addr got void * Fixes: 2554e6ba28a2 ("8250_men_mcb: Read num ports from register data.") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202307261517.x1O9OAkd-lkp@intel.com/ Signed-off-by: Jorge Sanjuan Garcia Link: https://lore.kernel.org/r/20230803095816.110864-1-jorge.sanjuangarcia@duagon.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index db62a3b15f19..dc9e093b1cb3 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -40,7 +40,7 @@ #define MEN_UART3_OFFSET (MEN_UART2_OFFSET + MEN_UART_MEM_SIZE) #define MEN_UART4_OFFSET (MEN_UART3_OFFSET + MEN_UART_MEM_SIZE) -#define MEN_READ_REGISTER(addr) readb((void *)addr) +#define MEN_READ_REGISTER(addr) readb(addr) #define MAX_PORTS 4 -- cgit v1.2.3 From 0aaf78182b721991a594ad8f8fe96d806e75db5a Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Wed, 9 Aug 2023 16:55:41 +0800 Subject: serial: sifive: Remove redundant of_match_ptr() The driver depends on CONFIG_OF, it is not necessary to use of_match_ptr() here. Signed-off-by: Ruan Jinjie Link: https://lore.kernel.org/r/20230809085541.2969654-1-ruanjinjie@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sifive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index 3ac9fbd0226e..e2efc3f84eff 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -1031,7 +1031,7 @@ static struct platform_driver sifive_serial_platform_driver = { .remove = sifive_serial_remove, .driver = { .name = SIFIVE_SERIAL_NAME, - .of_match_table = of_match_ptr(sifive_serial_of_match), + .of_match_table = sifive_serial_of_match, }, }; -- cgit v1.2.3 From 9c8441330bb399cba6177acce9b0e68c0dbaa597 Mon Sep 17 00:00:00 2001 From: Vijaya Krishna Nivarthi Date: Wed, 9 Aug 2023 16:23:13 +0530 Subject: tty: serial: qcom-geni-serial: Poll primary sequencer irq status after cancel_tx TX is handled by primary sequencer. After cancelling primary command, poll primary sequencer's irq status instead of that of secondary. While at it, also remove a couple of redundant lines that read from IRQ_EN register and write back same. Fixes: 2aaa43c70778 ("tty: serial: qcom-geni-serial: add support for serial engine DMA") Signed-off-by: Vijaya Krishna Nivarthi Link: https://lore.kernel.org/r/1691578393-9891-1-git-send-email-quic_vnivarth@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 3ca5db294be3..b8aa4c1293ba 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -591,7 +591,6 @@ static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport) { struct qcom_geni_serial_port *port = to_dev_port(uport); bool done; - u32 m_irq_en; if (!qcom_geni_serial_main_active(uport)) return; @@ -603,12 +602,10 @@ static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport) port->tx_remaining = 0; } - m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); - writel(m_irq_en, uport->membase + SE_GENI_M_IRQ_EN); geni_se_cancel_m_cmd(&port->se); - done = qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS, - S_CMD_CANCEL_EN, true); + done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, + M_CMD_CANCEL_EN, true); if (!done) { geni_se_abort_m_cmd(&port->se); done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, -- cgit v1.2.3 From ebf9ec7a4554632d9e621a4c00618c7c10a3e0fa Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:35 +0200 Subject: tty: xtensa/iss: drop unneeded tty_operations hooks All ::flush_chars(), ::hangup(), and ::wait_until_sent() from struct tty_operations are optional. There is no need to provide them with empty bodies. tty_operations::put_char() needs not be provided if it is the same as tty_operations::write(tty, &ch, 1). So drop all of them. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Chris Zankel Cc: Max Filippov Acked-by: Max Filippov Link: https://lore.kernel.org/r/20230810091510.13006-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/xtensa/platforms/iss/console.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 10b79d3c74e0..b40b73809dd8 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -82,32 +82,12 @@ static void rs_poll(struct timer_list *unused) mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); } - -static int rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - return rs_write(tty, &ch, 1); -} - -static void rs_flush_chars(struct tty_struct *tty) -{ -} - static unsigned int rs_write_room(struct tty_struct *tty) { /* Let's say iss can always accept 2K characters.. */ return 2 * 1024; } -static void rs_hangup(struct tty_struct *tty) -{ - /* Stub, once again.. */ -} - -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - /* Stub, once again.. */ -} - static int rs_proc_show(struct seq_file *m, void *v) { seq_printf(m, "serinfo:1.0 driver:0.1\n"); @@ -118,11 +98,7 @@ static const struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, - .put_char = rs_put_char, - .flush_chars = rs_flush_chars, .write_room = rs_write_room, - .hangup = rs_hangup, - .wait_until_sent = rs_wait_until_sent, .proc_show = rs_proc_show, }; -- cgit v1.2.3 From abb05ac9f78b3760d118d17e69e27367a5f0a9d7 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:36 +0200 Subject: tty: ldisc: document that ldops are optional There is no need to provide any hook in struct tty_ldisc_ops. Document that and write down that read/write return EIO in that case. The rest is simply ignored. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- include/linux/tty_ldisc.h | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 49dc172dedc7..62e089434995 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -71,7 +71,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * call to @receive_buf(). Returning an error will prevent the ldisc from * being attached. * - * Can sleep. + * Optional. Can sleep. * * @close: [TTY] ``void ()(struct tty_struct *tty)`` * @@ -80,7 +80,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * changed to use a new line discipline. At the point of execution no * further users will enter the ldisc code for this tty. * - * Can sleep. + * Optional. Can sleep. * * @flush_buffer: [TTY] ``void ()(struct tty_struct *tty)`` * @@ -88,6 +88,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * input characters it may have queued to be delivered to the user mode * process. It may be called at any point between open and close. * + * Optional. + * * @read: [TTY] ``ssize_t ()(struct tty_struct *tty, struct file *file, * unsigned char *buf, size_t nr)`` * @@ -97,7 +99,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * an %EIO error. Multiple read calls may occur in parallel and the ldisc * must deal with serialization issues. * - * Can sleep. + * Optional: %EIO unless provided. Can sleep. * * @write: [TTY] ``ssize_t ()(struct tty_struct *tty, struct file *file, * const unsigned char *buf, size_t nr)`` @@ -108,7 +110,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * characters first. If this function is not defined, the user will * receive an %EIO error. * - * Can sleep. + * Optional: %EIO unless provided. Can sleep. * * @ioctl: [TTY] ``int ()(struct tty_struct *tty, unsigned int cmd, * unsigned long arg)`` @@ -120,6 +122,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * discpline. So a low-level driver can "grab" an ioctl request before * the line discpline has a chance to see it. * + * Optional. + * * @compat_ioctl: [TTY] ``int ()(struct tty_struct *tty, unsigned int cmd, * unsigned long arg)`` * @@ -130,11 +134,15 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * a pointer to wordsize-sensitive structure belongs here, but most of * ldiscs will happily leave it %NULL. * + * Optional. + * * @set_termios: [TTY] ``void ()(struct tty_struct *tty, const struct ktermios *old)`` * * This function notifies the line discpline that a change has been made * to the termios structure. * + * Optional. + * * @poll: [TTY] ``int ()(struct tty_struct *tty, struct file *file, * struct poll_table_struct *wait)`` * @@ -142,6 +150,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * device. It is solely the responsibility of the line discipline to * handle poll requests. * + * Optional. + * * @hangup: [TTY] ``void ()(struct tty_struct *tty)`` * * Called on a hangup. Tells the discipline that it should cease I/O to @@ -149,7 +159,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * but should wait until any pending driver I/O is completed. No further * calls into the ldisc code will occur. * - * Can sleep. + * Optional. Can sleep. * * @receive_buf: [DRV] ``void ()(struct tty_struct *tty, * const unsigned char *cp, const char *fp, int count)`` @@ -161,6 +171,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * character was received with a parity error, etc. @fp may be %NULL to * indicate all data received is %TTY_NORMAL. * + * Optional. + * * @write_wakeup: [DRV] ``void ()(struct tty_struct *tty)`` * * This function is called by the low-level tty driver to signal that line @@ -170,11 +182,15 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * send, please arise a tasklet or workqueue to do the real data transfer. * Do not send data in this hook, it may lead to a deadlock. * + * Optional. + * * @dcd_change: [DRV] ``void ()(struct tty_struct *tty, bool active)`` * * Tells the discipline that the DCD pin has changed its status. Used * exclusively by the %N_PPS (Pulse-Per-Second) line discipline. * + * Optional. + * * @receive_buf2: [DRV] ``int ()(struct tty_struct *tty, * const unsigned char *cp, const char *fp, int count)`` * @@ -186,6 +202,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * indicate all data received is %TTY_NORMAL. If assigned, prefer this * function for automatic flow control. * + * Optional. + * * @lookahead_buf: [DRV] ``void ()(struct tty_struct *tty, * const unsigned char *cp, const char *fp, int count)`` * @@ -198,6 +216,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * same characters (e.g. by skipping the actions for high-priority * characters already handled by ->lookahead_buf()). * + * Optional. + * * @owner: module containting this ldisc (for reference counting) * * This structure defines the interface between the tty line discipline -- cgit v1.2.3 From 6e5710e71df19804f921f193744d615912b7a7cb Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:37 +0200 Subject: tty: remove dummy tty_ldisc_ops::poll() implementations tty_ldisc_ops::poll() is optional and needs not be provided. It is equal to returning 0. So remove all those from the code. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230810091510.13006-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_ldisc.c | 7 ------- drivers/net/ppp/ppp_async.c | 8 -------- drivers/net/ppp/ppp_synctty.c | 8 -------- net/nfc/nci/uart.c | 7 ------- 4 files changed, 30 deletions(-) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index efdda2c3fce8..5224b0961200 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -818,12 +818,6 @@ static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, return 0; } -static __poll_t hci_uart_tty_poll(struct tty_struct *tty, - struct file *filp, poll_table *wait) -{ - return 0; -} - static struct tty_ldisc_ops hci_uart_ldisc = { .owner = THIS_MODULE, .num = N_HCI, @@ -834,7 +828,6 @@ static struct tty_ldisc_ops hci_uart_ldisc = { .write = hci_uart_tty_write, .ioctl = hci_uart_tty_ioctl, .compat_ioctl = hci_uart_tty_ioctl, - .poll = hci_uart_tty_poll, .receive_buf = hci_uart_tty_receive, .write_wakeup = hci_uart_tty_wakeup, }; diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index 15a179631903..f420bddb6a8c 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -328,13 +328,6 @@ ppp_asynctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) return err; } -/* No kernel lock - fine */ -static __poll_t -ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) -{ - return 0; -} - /* May sleep, don't call from interrupt level or with interrupts disabled */ static void ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, @@ -378,7 +371,6 @@ static struct tty_ldisc_ops ppp_ldisc = { .read = ppp_asynctty_read, .write = ppp_asynctty_write, .ioctl = ppp_asynctty_ioctl, - .poll = ppp_asynctty_poll, .receive_buf = ppp_asynctty_receive, .write_wakeup = ppp_asynctty_wakeup, }; diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 18283b7b94bc..86dacef84c6c 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -321,13 +321,6 @@ ppp_synctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) return err; } -/* No kernel lock - fine */ -static __poll_t -ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) -{ - return 0; -} - /* May sleep, don't call from interrupt level or with interrupts disabled */ static void ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, @@ -371,7 +364,6 @@ static struct tty_ldisc_ops ppp_sync_ldisc = { .read = ppp_sync_read, .write = ppp_sync_write, .ioctl = ppp_synctty_ioctl, - .poll = ppp_sync_poll, .receive_buf = ppp_sync_receive, .write_wakeup = ppp_sync_wakeup, }; diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index 082f94be0996..c8249d95306d 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -357,12 +357,6 @@ static ssize_t nci_uart_tty_write(struct tty_struct *tty, struct file *file, return 0; } -static __poll_t nci_uart_tty_poll(struct tty_struct *tty, - struct file *filp, poll_table *wait) -{ - return 0; -} - static int nci_uart_send(struct nci_uart *nu, struct sk_buff *skb) { /* Queue TX packet */ @@ -435,7 +429,6 @@ static struct tty_ldisc_ops nci_uart_ldisc = { .close = nci_uart_tty_close, .read = nci_uart_tty_read, .write = nci_uart_tty_write, - .poll = nci_uart_tty_poll, .receive_buf = nci_uart_tty_receive, .write_wakeup = nci_uart_tty_wakeup, .ioctl = nci_uart_tty_ioctl, -- cgit v1.2.3 From 1d28dfedd204c6ae58c9f08990a0c8fb1f63dd18 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:38 +0200 Subject: tty: n_null: remove optional ldops Only tty_ldisc_ops::read() and ::write() of n_null behave differently than the default ldops implementations. They return %EOPNOTSUPP instead of %EIO. So keep only those two and remove the rest ldops as they are superfluous. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-5-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_null.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/tty/n_null.c b/drivers/tty/n_null.c index f913b665af72..4a0d8bb2fb4c 100644 --- a/drivers/tty/n_null.c +++ b/drivers/tty/n_null.c @@ -10,15 +10,6 @@ * Copyright (C) Intel 2017 */ -static int n_null_open(struct tty_struct *tty) -{ - return 0; -} - -static void n_null_close(struct tty_struct *tty) -{ -} - static ssize_t n_null_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr, void **cookie, unsigned long offset) @@ -32,21 +23,12 @@ static ssize_t n_null_write(struct tty_struct *tty, struct file *file, return -EOPNOTSUPP; } -static void n_null_receivebuf(struct tty_struct *tty, - const unsigned char *cp, const char *fp, - int cnt) -{ -} - static struct tty_ldisc_ops null_ldisc = { .owner = THIS_MODULE, .num = N_NULL, .name = "n_null", - .open = n_null_open, - .close = n_null_close, .read = n_null_read, .write = n_null_write, - .receive_buf = n_null_receivebuf }; static int __init n_null_init(void) -- cgit v1.2.3 From af815336556df28f800669c58ab3bdad7d786b98 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:39 +0200 Subject: tty: change tty_write_lock()'s ndelay parameter to bool It's a yes-no parameter, so convert it to bool to be obvious. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-6-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty.h | 2 +- drivers/tty/tty_io.c | 6 +++--- drivers/tty/tty_ioctl.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 89769a1f1f97..2751ac3946e7 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -63,7 +63,7 @@ int tty_check_change(struct tty_struct *tty); void __stop_tty(struct tty_struct *tty); void __start_tty(struct tty_struct *tty); void tty_write_unlock(struct tty_struct *tty); -int tty_write_lock(struct tty_struct *tty, int ndelay); +int tty_write_lock(struct tty_struct *tty, bool ndelay); void tty_vhangup_session(struct tty_struct *tty); void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); int tty_signal_session_leader(struct tty_struct *tty, int exit_session); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index eb4e2e0e300d..54036a20a102 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -946,7 +946,7 @@ void tty_write_unlock(struct tty_struct *tty) wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); } -int tty_write_lock(struct tty_struct *tty, int ndelay) +int tty_write_lock(struct tty_struct *tty, bool ndelay) { if (!mutex_trylock(&tty->atomic_write_lock)) { if (ndelay) @@ -1160,7 +1160,7 @@ int tty_send_xchar(struct tty_struct *tty, char ch) return 0; } - if (tty_write_lock(tty, 0) < 0) + if (tty_write_lock(tty, false) < 0) return -ERESTARTSYS; down_read(&tty->termios_rwsem); @@ -2486,7 +2486,7 @@ static int send_break(struct tty_struct *tty, unsigned int duration) retval = tty->ops->break_ctl(tty, duration); else { /* Do the work ourselves */ - if (tty_write_lock(tty, 0) < 0) + if (tty_write_lock(tty, false) < 0) return -EINTR; retval = tty->ops->break_ctl(tty, -1); if (retval) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 2e88b414cf95..e3e1318f53fd 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -507,7 +507,7 @@ retry_write_wait: if (retval < 0) return retval; - if (tty_write_lock(tty, 0) < 0) + if (tty_write_lock(tty, false) < 0) goto retry_write_wait; /* Racing writer? */ -- cgit v1.2.3 From c6e37fe04433684cadb99aa472b2959d500c5898 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:40 +0200 Subject: tty: tty_port: rename 'disc' to 'ld' Line discipline variables are named 'ld' all over the tty code. Rename these in tty_port, so that it is easier to grep for the code (namely for "ld->ops"). Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-7-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index a788a6bf487d..cda33dec73c3 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -26,19 +26,19 @@ static int tty_port_default_receive_buf(struct tty_port *port, { int ret; struct tty_struct *tty; - struct tty_ldisc *disc; + struct tty_ldisc *ld; tty = READ_ONCE(port->itty); if (!tty) return 0; - disc = tty_ldisc_ref(tty); - if (!disc) + ld = tty_ldisc_ref(tty); + if (!ld) return 0; - ret = tty_ldisc_receive_buf(disc, p, (char *)f, count); + ret = tty_ldisc_receive_buf(ld, p, (char *)f, count); - tty_ldisc_deref(disc); + tty_ldisc_deref(ld); return ret; } @@ -47,20 +47,20 @@ static void tty_port_default_lookahead_buf(struct tty_port *port, const unsigned const unsigned char *f, unsigned int count) { struct tty_struct *tty; - struct tty_ldisc *disc; + struct tty_ldisc *ld; tty = READ_ONCE(port->itty); if (!tty) return; - disc = tty_ldisc_ref(tty); - if (!disc) + ld = tty_ldisc_ref(tty); + if (!ld) return; - if (disc->ops->lookahead_buf) - disc->ops->lookahead_buf(disc->tty, p, f, count); + if (ld->ops->lookahead_buf) + ld->ops->lookahead_buf(ld->tty, p, f, count); - tty_ldisc_deref(disc); + tty_ldisc_deref(ld); } static void tty_port_default_wakeup(struct tty_port *port) -- cgit v1.2.3 From d1150d29906cdfddf8a43aaf5a4cafa4f22474fa Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:41 +0200 Subject: tty: drop tty_debug_wait_until_sent() It's a nop for everyone as TTY_DEBUG_WAIT_UNTIL_SENT is never set. Provided, we have better debugging/printout mechanisms nowadays, remove this mechanism. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-8-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index e3e1318f53fd..f63e8b1b9e40 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -28,14 +28,6 @@ #include #include -#undef TTY_DEBUG_WAIT_UNTIL_SENT - -#ifdef TTY_DEBUG_WAIT_UNTIL_SENT -# define tty_debug_wait_until_sent(tty, f, args...) tty_debug(tty, f, ##args) -#else -# define tty_debug_wait_until_sent(tty, f, args...) do {} while (0) -#endif - #undef DEBUG /* @@ -198,8 +190,6 @@ int tty_unthrottle_safe(struct tty_struct *tty) void tty_wait_until_sent(struct tty_struct *tty, long timeout) { - tty_debug_wait_until_sent(tty, "wait until sent, timeout=%ld\n", timeout); - if (!timeout) timeout = MAX_SCHEDULE_TIMEOUT; -- cgit v1.2.3 From 77b425e4efe5a40cab602bb6538d8d27ba4d9948 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:42 +0200 Subject: tty: make tty_change_softcar() more understandable * rename 'arg' to 'enable' as that is what it means. * make 'bit' a tcflag_t, not int, as that is what cflags are. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-9-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index f63e8b1b9e40..7958bf6d27c4 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -737,17 +737,17 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) /** * tty_change_softcar - carrier change ioctl helper * @tty: tty to update - * @arg: enable/disable CLOCAL + * @enable: enable/disable CLOCAL * * Perform a change to the CLOCAL state and call into the driver * layer to make it visible. All done with the termios rwsem */ -static int tty_change_softcar(struct tty_struct *tty, int arg) +static int tty_change_softcar(struct tty_struct *tty, bool enable) { int ret = 0; - int bit = arg ? CLOCAL : 0; struct ktermios old; + tcflag_t bit = enable ? CLOCAL : 0; down_write(&tty->termios_rwsem); old = tty->termios; -- cgit v1.2.3 From 0b7a2b282959d3311f158629f67c6d681a3dc2b3 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:43 +0200 Subject: tty: make tty_port_client_operations operate with u8 The parameters are already unsigned chars. So make them explicitly u8s, as the rest is going to be unified to u8 eventually too. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Rob Herring Link: https://lore.kernel.org/r/20230810091510.13006-10-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serdev/serdev-ttyport.c | 4 ++-- drivers/tty/tty_buffer.c | 4 ++-- drivers/tty/tty_port.c | 9 ++++----- include/linux/tty_port.h | 7 ++++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index 8033ef19669c..f69ae27838e3 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -22,8 +22,8 @@ struct serport { * Callback functions from the tty port. */ -static int ttyport_receive_buf(struct tty_port *port, const unsigned char *cp, - const unsigned char *fp, size_t count) +static int ttyport_receive_buf(struct tty_port *port, const u8 *cp, + const u8 *fp, size_t count) { struct serdev_controller *ctrl = port->client_data; struct serport *serport = serdev_controller_get_drvdata(ctrl); diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 2df86ed90574..42464c37125a 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -505,8 +505,8 @@ static void lookahead_bufs(struct tty_port *port, struct tty_buffer *head) static int receive_buf(struct tty_port *port, struct tty_buffer *head, int count) { - unsigned char *p = char_buf_ptr(head, head->read); - const char *f = NULL; + u8 *p = char_buf_ptr(head, head->read); + const u8 *f = NULL; int n; if (head->flags) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index cda33dec73c3..6bf58980c81d 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -20,9 +20,8 @@ #include #include "tty.h" -static int tty_port_default_receive_buf(struct tty_port *port, - const unsigned char *p, - const unsigned char *f, size_t count) +static int tty_port_default_receive_buf(struct tty_port *port, const u8 *p, + const u8 *f, size_t count) { int ret; struct tty_struct *tty; @@ -43,8 +42,8 @@ static int tty_port_default_receive_buf(struct tty_port *port, return ret; } -static void tty_port_default_lookahead_buf(struct tty_port *port, const unsigned char *p, - const unsigned char *f, unsigned int count) +static void tty_port_default_lookahead_buf(struct tty_port *port, const u8 *p, + const u8 *f, unsigned int count) { struct tty_struct *tty; struct tty_ldisc *ld; diff --git a/include/linux/tty_port.h b/include/linux/tty_port.h index edf685a24f7c..726575743367 100644 --- a/include/linux/tty_port.h +++ b/include/linux/tty_port.h @@ -39,9 +39,10 @@ struct tty_port_operations { }; struct tty_port_client_operations { - int (*receive_buf)(struct tty_port *port, const unsigned char *, const unsigned char *, size_t); - void (*lookahead_buf)(struct tty_port *port, const unsigned char *cp, - const unsigned char *fp, unsigned int count); + int (*receive_buf)(struct tty_port *port, const u8 *cp, const u8 *fp, + size_t count); + void (*lookahead_buf)(struct tty_port *port, const u8 *cp, + const u8 *fp, unsigned int count); void (*write_wakeup)(struct tty_port *port); }; -- cgit v1.2.3 From 0468a8071d7cfb0f5bc02b0888cec4525551299f Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:44 +0200 Subject: tty: make counts in tty_port_client_operations hooks size_t The counts in tty_port_client_operations hooks' are currently represented by all 'int', 'unsigned int', and 'size_t'. Unify them all to unsigned 'size_t' for clarity. Note that size_t is used already in tty_buffer.c. So, eventually, it is spread for counts everywhere and this is the beginning. So the two changes namely: * ::receive_buf() is called from tty_ldisc_receive_buf(). And that expects values ">= 0" from ::receive_buf(), so switch its rettype to size_t is fine. tty_ldisc_receive_buf() types will be changed separately. * ::lookahead_buf()'s count comes from lookahead_bufs() and is already 'unsigned int'. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Rob Herring Link: https://lore.kernel.org/r/20230810091510.13006-11-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serdev/serdev-ttyport.c | 4 ++-- drivers/tty/tty_port.c | 11 +++++------ include/linux/tty_port.h | 6 +++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index f69ae27838e3..e3856814ce77 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -22,8 +22,8 @@ struct serport { * Callback functions from the tty port. */ -static int ttyport_receive_buf(struct tty_port *port, const u8 *cp, - const u8 *fp, size_t count) +static size_t ttyport_receive_buf(struct tty_port *port, const u8 *cp, + const u8 *fp, size_t count) { struct serdev_controller *ctrl = port->client_data; struct serport *serport = serdev_controller_get_drvdata(ctrl); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 6bf58980c81d..7fd171b7c844 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -20,10 +20,9 @@ #include #include "tty.h" -static int tty_port_default_receive_buf(struct tty_port *port, const u8 *p, - const u8 *f, size_t count) +static size_t tty_port_default_receive_buf(struct tty_port *port, const u8 *p, + const u8 *f, size_t count) { - int ret; struct tty_struct *tty; struct tty_ldisc *ld; @@ -35,15 +34,15 @@ static int tty_port_default_receive_buf(struct tty_port *port, const u8 *p, if (!ld) return 0; - ret = tty_ldisc_receive_buf(ld, p, (char *)f, count); + count = tty_ldisc_receive_buf(ld, p, (char *)f, count); tty_ldisc_deref(ld); - return ret; + return count; } static void tty_port_default_lookahead_buf(struct tty_port *port, const u8 *p, - const u8 *f, unsigned int count) + const u8 *f, size_t count) { struct tty_struct *tty; struct tty_ldisc *ld; diff --git a/include/linux/tty_port.h b/include/linux/tty_port.h index 726575743367..6b367eb17979 100644 --- a/include/linux/tty_port.h +++ b/include/linux/tty_port.h @@ -39,10 +39,10 @@ struct tty_port_operations { }; struct tty_port_client_operations { - int (*receive_buf)(struct tty_port *port, const u8 *cp, const u8 *fp, - size_t count); + size_t (*receive_buf)(struct tty_port *port, const u8 *cp, const u8 *fp, + size_t count); void (*lookahead_buf)(struct tty_port *port, const u8 *cp, - const u8 *fp, unsigned int count); + const u8 *fp, size_t count); void (*write_wakeup)(struct tty_port *port); }; -- cgit v1.2.3 From 201560af612c12f43211a881edd378727a9a52d6 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:45 +0200 Subject: tty: switch receive_buf() counts to size_t 'size_t' is what receive_buf() expects and returns while handling count. So switch to 'size_t'. This renders both local 'count' and 'rcvd' in flush_to_ldisc() to be size_t too. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-12-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 42464c37125a..7182dab60fac 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -502,12 +502,12 @@ static void lookahead_bufs(struct tty_port *port, struct tty_buffer *head) } } -static int -receive_buf(struct tty_port *port, struct tty_buffer *head, int count) +static size_t +receive_buf(struct tty_port *port, struct tty_buffer *head, size_t count) { u8 *p = char_buf_ptr(head, head->read); const u8 *f = NULL; - int n; + size_t n; if (head->flags) f = flag_buf_ptr(head, head->read); @@ -539,7 +539,7 @@ static void flush_to_ldisc(struct work_struct *work) while (1) { struct tty_buffer *head = buf->head; struct tty_buffer *next; - int count, rcvd; + size_t count, rcvd; /* Ldisc or user is trying to gain exclusive access */ if (atomic_read(&buf->priority)) -- cgit v1.2.3 From 8d9526f99fc39ebaca173eda646818023e7f0730 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:46 +0200 Subject: tty: switch count in tty_ldisc_receive_buf() to size_t It comes from both paste_selection() and tty_port_default_receive_buf() as unsigned (int and size_t respectively). Switch to size_t to converge to that eventually. Return the count as size_t too (the two callers above expect that). Switch paste_selection()'s type of 'count' too, so that the returned and passed type match. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-13-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 6 +++--- drivers/tty/vt/selection.c | 2 +- include/linux/tty_flip.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 7182dab60fac..56f5732ce47f 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -450,13 +450,13 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); * * Returns: the number of bytes processed. */ -int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, - const char *f, int count) +size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, + const char *f, size_t count) { if (ld->ops->receive_buf2) count = ld->ops->receive_buf2(ld->tty, p, f, count); else { - count = min_t(int, count, ld->tty->receive_room); + count = min_t(size_t, count, ld->tty->receive_room); if (count && ld->ops->receive_buf) ld->ops->receive_buf(ld->tty, p, f, count); } diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 6ef22f01cc51..8967c3a0d916 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -376,7 +376,7 @@ int paste_selection(struct tty_struct *tty) { struct vc_data *vc = tty->driver_data; int pasted = 0; - unsigned int count; + size_t count; struct tty_ldisc *ld; DECLARE_WAITQUEUE(wait, current); int ret = 0; diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index bfaaeee61a05..09c4dbcd0025 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -41,8 +41,8 @@ static inline int tty_insert_flip_string(struct tty_port *port, return tty_insert_flip_string_fixed_flag(port, chars, TTY_NORMAL, size); } -int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, - const char *f, int count); +size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, + const char *f, size_t count); void tty_buffer_lock_exclusive(struct tty_port *port); void tty_buffer_unlock_exclusive(struct tty_port *port); -- cgit v1.2.3 From 94b580e308c67922514af146a8793292d60a9b18 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:47 +0200 Subject: tty: can327: unify error paths in can327_ldisc_rx() Create a label with can327_uart_side_failure() and spin unlock. And jump there from all three fail paths. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Max Staudt Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: linux-can@vger.kernel.org Link: https://lore.kernel.org/r/20230810091510.13006-14-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/can327.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c index ee8a977acc8d..05e9c035e8f6 100644 --- a/drivers/net/can/can327.c +++ b/drivers/net/can/can327.c @@ -905,11 +905,7 @@ static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, if (fp && *fp++) { netdev_err(elm->dev, "Error in received character stream. Check your wiring."); - - can327_uart_side_failure(elm); - - spin_unlock_bh(&elm->lock); - return; + goto uart_failure; } /* Ignore NUL characters, which the PIC microcontroller may @@ -925,10 +921,7 @@ static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, netdev_err(elm->dev, "Received illegal character %02x.\n", *cp); - can327_uart_side_failure(elm); - - spin_unlock_bh(&elm->lock); - return; + goto uart_failure; } elm->rxbuf[elm->rxfill++] = *cp; @@ -941,15 +934,16 @@ static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, netdev_err(elm->dev, "Receive buffer overflowed. Bad chip or wiring? count = %i", count); - - can327_uart_side_failure(elm); - - spin_unlock_bh(&elm->lock); - return; + goto uart_failure; } can327_parse_rxbuf(elm, first_new_char_idx); spin_unlock_bh(&elm->lock); + + return; +uart_failure: + can327_uart_side_failure(elm); + spin_unlock_bh(&elm->lock); } /* Write out remaining transmit buffer. -- cgit v1.2.3 From 73048bd55e6b034a76812140de418974c7ceb736 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:48 +0200 Subject: tty: can327, move overflow test inside can327_ldisc_rx()'s loop The 'count' is going to be unsigned and the 'count >= 0' test would be always true then. Move the condition to the loop where this is easier to check. It looks as is easier to follow after all too. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Max Staudt Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: linux-can@vger.kernel.org Link: https://lore.kernel.org/r/20230810091510.13006-15-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/can327.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c index 05e9c035e8f6..4533dc00f215 100644 --- a/drivers/net/can/can327.c +++ b/drivers/net/can/can327.c @@ -901,7 +901,13 @@ static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, */ first_new_char_idx = elm->rxfill; - while (count-- && elm->rxfill < CAN327_SIZE_RXBUF) { + while (count--) { + if (elm->rxfill >= CAN327_SIZE_RXBUF) { + netdev_err(elm->dev, + "Receive buffer overflowed. Bad chip or wiring? count = %i", + count); + goto uart_failure; + } if (fp && *fp++) { netdev_err(elm->dev, "Error in received character stream. Check your wiring."); @@ -930,13 +936,6 @@ static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, cp++; } - if (count >= 0) { - netdev_err(elm->dev, - "Receive buffer overflowed. Bad chip or wiring? count = %i", - count); - goto uart_failure; - } - can327_parse_rxbuf(elm, first_new_char_idx); spin_unlock_bh(&elm->lock); -- cgit v1.2.3 From e8161447bb0ce2d59277e9276012dd1c6f357850 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:49 +0200 Subject: tty: make tty_ldisc_ops::*buf*() hooks operate on size_t Count passed to tty_ldisc_ops::receive_buf*(), ::lookahead_buf(), and returned from ::receive_buf2() is expected to be size_t. So set it to size_t to unify with the rest of the code. Signed-off-by: "Jiri Slaby (SUSE)" Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Cc: Samuel Thibault Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: Dmitry Torokhov Cc: Arnd Bergmann Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Max Staudt Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: Dario Binacchi Cc: Andreas Koensgen Cc: Jeremy Kerr Cc: Matt Johnston Cc: Krzysztof Kozlowski Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Acked-by: Mark Brown Link: https://lore.kernel.org/r/20230810091510.13006-16-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 6 +++--- drivers/bluetooth/hci_ldisc.c | 2 +- drivers/input/serio/serport.c | 3 ++- drivers/misc/ti-st/st_core.c | 2 +- drivers/net/caif/caif_serial.c | 2 +- drivers/net/can/can327.c | 4 ++-- drivers/net/can/slcan/slcan-core.c | 2 +- drivers/net/hamradio/6pack.c | 2 +- drivers/net/hamradio/mkiss.c | 2 +- drivers/net/mctp/mctp-serial.c | 2 +- drivers/net/ppp/ppp_async.c | 2 +- drivers/net/ppp/ppp_synctty.c | 2 +- drivers/net/slip/slip.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/tty/n_hdlc.c | 4 ++-- drivers/tty/n_tty.c | 14 ++++++++------ include/linux/tty_ldisc.h | 16 ++++++++-------- net/nfc/nci/uart.c | 2 +- sound/soc/codecs/cx20442.c | 2 +- 19 files changed, 38 insertions(+), 35 deletions(-) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 5d4bafe118ec..736f622068ce 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -71,9 +71,9 @@ static void spk_ttyio_ldisc_close(struct tty_struct *tty) kfree(tty->disc_data); } -static int spk_ttyio_receive_buf2(struct tty_struct *tty, - const unsigned char *cp, - const char *fp, int count) +static size_t spk_ttyio_receive_buf2(struct tty_struct *tty, + const unsigned char *cp, const char *fp, + size_t count) { struct spk_ldisc_data *ldisc_data = tty->disc_data; struct spk_synth *synth = ldisc_data->synth; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 5224b0961200..32bef61c5901 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -599,7 +599,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) * Return Value: None */ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, - const char *flags, int count) + const char *flags, size_t count) { struct hci_uart *hu = tty->disc_data; diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index a5d8953f5904..7fc6155131f8 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -115,7 +115,8 @@ static void serport_ldisc_close(struct tty_struct *tty) */ static void serport_ldisc_receive(struct tty_struct *tty, - const unsigned char *cp, const char *fp, int count) + const unsigned char *cp, const char *fp, + size_t count) { struct serport *serport = tty->disc_data; unsigned long flags; diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 3b2145722bd7..c89024ab3d77 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -792,7 +792,7 @@ static void st_tty_close(struct tty_struct *tty) } static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, - const char *tty_flags, int count) + const char *tty_flags, size_t count) { #ifdef VERBOSE print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 688075859ae4..feda04dbe837 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -159,7 +159,7 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size) #endif static void ldisc_receive(struct tty_struct *tty, const u8 *data, - const char *flags, int count) + const char *flags, size_t count) { struct sk_buff *skb = NULL; struct ser_device *ser; diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c index 4533dc00f215..4bf970df7e84 100644 --- a/drivers/net/can/can327.c +++ b/drivers/net/can/can327.c @@ -886,7 +886,7 @@ static bool can327_is_valid_rx_char(u8 c) * functions may be called in parallel. */ static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count) + const char *fp, size_t count) { struct can327 *elm = tty->disc_data; size_t first_new_char_idx; @@ -904,7 +904,7 @@ static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, while (count--) { if (elm->rxfill >= CAN327_SIZE_RXBUF) { netdev_err(elm->dev, - "Receive buffer overflowed. Bad chip or wiring? count = %i", + "Receive buffer overflowed. Bad chip or wiring? count = %zu", count); goto uart_failure; } diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c index 371af9d17b14..63371563d8e2 100644 --- a/drivers/net/can/slcan/slcan-core.c +++ b/drivers/net/can/slcan/slcan-core.c @@ -776,7 +776,7 @@ static const struct net_device_ops slcan_netdev_ops = { */ static void slcan_receive_buf(struct tty_struct *tty, const unsigned char *cp, const char *fp, - int count) + size_t count) { struct slcan *sl = tty->disc_data; diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 9fb567524220..2089efb0d360 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -428,7 +428,7 @@ out: * and sent on to some IP layer for further processing. */ static void sixpack_receive_buf(struct tty_struct *tty, - const unsigned char *cp, const char *fp, int count) + const unsigned char *cp, const char *fp, size_t count) { struct sixpack *sp; int count1; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index c251e04ae047..1efab6037c7e 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -875,7 +875,7 @@ static int mkiss_ioctl(struct tty_struct *tty, unsigned int cmd, * and sent on to the AX.25 layer for further processing. */ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count) + const char *fp, size_t count) { struct mkiss *ax = mkiss_get(tty); diff --git a/drivers/net/mctp/mctp-serial.c b/drivers/net/mctp/mctp-serial.c index 9f9eaf896047..6761f4ff2e7c 100644 --- a/drivers/net/mctp/mctp-serial.c +++ b/drivers/net/mctp/mctp-serial.c @@ -392,7 +392,7 @@ static void mctp_serial_push(struct mctp_serial *dev, unsigned char c) static void mctp_serial_tty_receive_buf(struct tty_struct *tty, const unsigned char *c, - const char *f, int len) + const char *f, size_t len) { struct mctp_serial *dev = tty->disc_data; int i; diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index f420bddb6a8c..79b8fca47edb 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -331,7 +331,7 @@ ppp_asynctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) /* May sleep, don't call from interrupt level or with interrupts disabled */ static void ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, - const char *cflags, int count) + const char *cflags, size_t count) { struct asyncppp *ap = ap_get(tty); unsigned long flags; diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 86dacef84c6c..767aca32b315 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -324,7 +324,7 @@ ppp_synctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) /* May sleep, don't call from interrupt level or with interrupts disabled */ static void ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, - const char *cflags, int count) + const char *cflags, size_t count) { struct syncppp *ap = sp_get(tty); unsigned long flags; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 6865d32270e5..39450bf748a5 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -686,7 +686,7 @@ static void sl_setup(struct net_device *dev) */ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count) + const char *fp, size_t count) { struct slip *sl = tty->disc_data; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c7a787f10a9c..2f85877b8ba1 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3490,7 +3490,7 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) } static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count) + const char *fp, size_t count) { struct gsm_mux *gsm = tty->disc_data; char flags = TTY_NORMAL; diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 46b09bfb6f3a..ce3c779f5c03 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -370,12 +370,12 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) * interpreted as one HDLC frame. */ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, - const char *flags, int count) + const char *flags, size_t count) { register struct n_hdlc *n_hdlc = tty->disc_data; register struct n_hdlc_buf *buf; - pr_debug("%s() called count=%d\n", __func__, count); + pr_debug("%s() called count=%zu\n", __func__, count); if (count > maxframe) { pr_debug("rx count>maxframesize, data discarded\n"); diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0043cc84b91a..ee9b20dcbce6 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1480,7 +1480,7 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag) /* Caller must ensure count > 0 */ static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const unsigned char *cp, - const unsigned char *fp, unsigned int count) + const unsigned char *fp, size_t count) { struct n_tty_data *ldata = tty->disc_data; unsigned char flag = TTY_NORMAL; @@ -1662,12 +1662,13 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, * claims non-exclusive %termios_rwsem * publishes commit_head or canon_head */ -static int +static size_t n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, const char *fp, int count, int flow) { struct n_tty_data *ldata = tty->disc_data; - int room, n, rcvd = 0, overflow; + size_t rcvd = 0; + int room, n, overflow; down_read(&tty->termios_rwsem); @@ -1744,13 +1745,14 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, } static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count) + const char *fp, size_t count) { n_tty_receive_buf_common(tty, cp, fp, count, 0); } -static int n_tty_receive_buf2(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count) +static size_t n_tty_receive_buf2(struct tty_struct *tty, + const unsigned char *cp, const char *fp, + size_t count) { return n_tty_receive_buf_common(tty, cp, fp, count, 1); } diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 62e089434995..f88529e6a783 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -162,7 +162,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * Optional. Can sleep. * * @receive_buf: [DRV] ``void ()(struct tty_struct *tty, - * const unsigned char *cp, const char *fp, int count)`` + * const unsigned char *cp, const char *fp, size_t count)`` * * This function is called by the low-level tty driver to send characters * received by the hardware to the line discpline for processing. @cp is @@ -191,8 +191,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * * Optional. * - * @receive_buf2: [DRV] ``int ()(struct tty_struct *tty, - * const unsigned char *cp, const char *fp, int count)`` + * @receive_buf2: [DRV] ``ssize_t ()(struct tty_struct *tty, + * const unsigned char *cp, const char *fp, size_t count)`` * * This function is called by the low-level tty driver to send characters * received by the hardware to the line discpline for processing. @cp is a @@ -205,7 +205,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * Optional. * * @lookahead_buf: [DRV] ``void ()(struct tty_struct *tty, - * const unsigned char *cp, const char *fp, int count)`` + * const unsigned char *cp, const char *fp, size_t count)`` * * This function is called by the low-level tty driver for characters * not eaten by ->receive_buf() or ->receive_buf2(). It is useful for @@ -256,13 +256,13 @@ struct tty_ldisc_ops { * The following routines are called from below. */ void (*receive_buf)(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count); + const char *fp, size_t count); void (*write_wakeup)(struct tty_struct *tty); void (*dcd_change)(struct tty_struct *tty, bool active); - int (*receive_buf2)(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count); + size_t (*receive_buf2)(struct tty_struct *tty, const unsigned char *cp, + const char *fp, size_t count); void (*lookahead_buf)(struct tty_struct *tty, const unsigned char *cp, - const unsigned char *fp, unsigned int count); + const unsigned char *fp, size_t count); struct module *owner; }; diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index c8249d95306d..c957ca6d2f87 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -296,7 +296,7 @@ static int nci_uart_default_recv_buf(struct nci_uart *nu, const u8 *data, * Return Value: None */ static void nci_uart_tty_receive(struct tty_struct *tty, const u8 *data, - const char *flags, int count) + const char *flags, size_t count) { struct nci_uart *nu = tty->disc_data; diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 43c0cac0ec9e..42cc863cbd53 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -259,7 +259,7 @@ static void v253_hangup(struct tty_struct *tty) /* Line discipline .receive_buf() */ static void v253_receive(struct tty_struct *tty, const unsigned char *cp, - const char *fp, int count) + const char *fp, size_t count) { struct snd_soc_component *component = tty->disc_data; struct cx20442_priv *cx20442; -- cgit v1.2.3 From a8d9cd2318606627d3c0e4747dbd7bbc44c48e27 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:50 +0200 Subject: tty: use u8 for chars This makes all those 'unsigned char's an explicit 'u8'. This is part of the continuing unification of chars and flags to be consistent u8. This approaches tty_port_default_receive_buf(). Flags to be next. Signed-off-by: "Jiri Slaby (SUSE)" Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Cc: Samuel Thibault Cc: Dmitry Torokhov Cc: Arnd Bergmann Cc: Max Staudt Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Dario Binacchi Cc: Andreas Koensgen Cc: Jeremy Kerr Cc: Matt Johnston Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Peter Ujfalusi Acked-by: Mark Brown Link: https://lore.kernel.org/r/20230810091510.13006-17-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 5 ++--- drivers/input/serio/serport.c | 5 ++--- drivers/misc/ti-st/st_core.c | 2 +- drivers/net/can/can327.c | 2 +- drivers/net/can/slcan/slcan-core.c | 5 ++--- drivers/net/hamradio/6pack.c | 4 ++-- drivers/net/hamradio/mkiss.c | 2 +- drivers/net/mctp/mctp-serial.c | 3 +-- drivers/net/ppp/ppp_async.c | 8 ++++---- drivers/net/ppp/ppp_synctty.c | 11 +++++------ drivers/net/slip/slip.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/tty/n_hdlc.c | 2 +- drivers/tty/n_tty.c | 28 ++++++++++++++-------------- drivers/tty/tty.h | 2 +- drivers/tty/tty_buffer.c | 21 ++++++++++----------- include/linux/tty_buffer.h | 4 ++-- include/linux/tty_flip.h | 22 ++++++++++------------ include/linux/tty_ldisc.h | 18 +++++++++--------- sound/soc/codecs/cx20442.c | 4 ++-- sound/soc/ti/ams-delta.c | 2 +- 21 files changed, 73 insertions(+), 81 deletions(-) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 736f622068ce..dd683a079c08 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -71,9 +71,8 @@ static void spk_ttyio_ldisc_close(struct tty_struct *tty) kfree(tty->disc_data); } -static size_t spk_ttyio_receive_buf2(struct tty_struct *tty, - const unsigned char *cp, const char *fp, - size_t count) +static size_t spk_ttyio_receive_buf2(struct tty_struct *tty, const u8 *cp, + const char *fp, size_t count) { struct spk_ldisc_data *ldisc_data = tty->disc_data; struct spk_synth *synth = ldisc_data->synth; diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 7fc6155131f8..8bf79d39964d 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -114,9 +114,8 @@ static void serport_ldisc_close(struct tty_struct *tty) * 'interrupt' routine. */ -static void serport_ldisc_receive(struct tty_struct *tty, - const unsigned char *cp, const char *fp, - size_t count) +static void serport_ldisc_receive(struct tty_struct *tty, const u8 *cp, + const char *fp, size_t count) { struct serport *serport = tty->disc_data; unsigned long flags; diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index c89024ab3d77..0ce4e46ff161 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -791,7 +791,7 @@ static void st_tty_close(struct tty_struct *tty) pr_debug("%s: done ", __func__); } -static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, +static void st_tty_receive(struct tty_struct *tty, const u8 *data, const char *tty_flags, size_t count) { #ifdef VERBOSE diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c index 4bf970df7e84..a054f5fd0d43 100644 --- a/drivers/net/can/can327.c +++ b/drivers/net/can/can327.c @@ -885,7 +885,7 @@ static bool can327_is_valid_rx_char(u8 c) * This will not be re-entered while running, but other ldisc * functions may be called in parallel. */ -static void can327_ldisc_rx(struct tty_struct *tty, const unsigned char *cp, +static void can327_ldisc_rx(struct tty_struct *tty, const u8 *cp, const char *fp, size_t count) { struct can327 *elm = tty->disc_data; diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c index 63371563d8e2..fe5671dbeb77 100644 --- a/drivers/net/can/slcan/slcan-core.c +++ b/drivers/net/can/slcan/slcan-core.c @@ -774,9 +774,8 @@ static const struct net_device_ops slcan_netdev_ops = { * be re-entered while running but other ldisc functions may be called * in parallel */ -static void slcan_receive_buf(struct tty_struct *tty, - const unsigned char *cp, const char *fp, - size_t count) +static void slcan_receive_buf(struct tty_struct *tty, const u8 *cp, + const char *fp, size_t count) { struct slcan *sl = tty->disc_data; diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 2089efb0d360..9a1f2a3f3b4f 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -427,8 +427,8 @@ out: * a block of 6pack data has been received, which can now be decapsulated * and sent on to some IP layer for further processing. */ -static void sixpack_receive_buf(struct tty_struct *tty, - const unsigned char *cp, const char *fp, size_t count) +static void sixpack_receive_buf(struct tty_struct *tty, const u8 *cp, + const char *fp, size_t count) { struct sixpack *sp; int count1; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 1efab6037c7e..26dbcf49bfa6 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -874,7 +874,7 @@ static int mkiss_ioctl(struct tty_struct *tty, unsigned int cmd, * a block of data has been received, which can now be decapsulated * and sent on to the AX.25 layer for further processing. */ -static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, +static void mkiss_receive_buf(struct tty_struct *tty, const u8 *cp, const char *fp, size_t count) { struct mkiss *ax = mkiss_get(tty); diff --git a/drivers/net/mctp/mctp-serial.c b/drivers/net/mctp/mctp-serial.c index 6761f4ff2e7c..5f809a18d308 100644 --- a/drivers/net/mctp/mctp-serial.c +++ b/drivers/net/mctp/mctp-serial.c @@ -390,8 +390,7 @@ static void mctp_serial_push(struct mctp_serial *dev, unsigned char c) } } -static void mctp_serial_tty_receive_buf(struct tty_struct *tty, - const unsigned char *c, +static void mctp_serial_tty_receive_buf(struct tty_struct *tty, const u8 *c, const char *f, size_t len) { struct mctp_serial *dev = tty->disc_data; diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index 79b8fca47edb..a661ccdea6ab 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -330,8 +330,8 @@ ppp_asynctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) /* May sleep, don't call from interrupt level or with interrupts disabled */ static void -ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, - const char *cflags, size_t count) +ppp_asynctty_receive(struct tty_struct *tty, const u8 *buf, const char *cflags, + size_t count) { struct asyncppp *ap = ap_get(tty); unsigned long flags; @@ -819,8 +819,8 @@ process_input_packet(struct asyncppp *ap) other ldisc functions but will not be re-entered */ static void -ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - const char *flags, int count) +ppp_async_input(struct asyncppp *ap, const u8 *buf, const char *flags, + int count) { struct sk_buff *skb; int c, i, j, n, s, f; diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 767aca32b315..2a5cf6be9591 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -93,8 +93,8 @@ static int ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, static void ppp_sync_process(struct tasklet_struct *t); static int ppp_sync_push(struct syncppp *ap); static void ppp_sync_flush_output(struct syncppp *ap); -static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf, - const char *flags, int count); +static void ppp_sync_input(struct syncppp *ap, const u8 *buf, const char *flags, + int count); static const struct ppp_channel_ops sync_ops = { .start_xmit = ppp_sync_send, @@ -323,8 +323,8 @@ ppp_synctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) /* May sleep, don't call from interrupt level or with interrupts disabled */ static void -ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, - const char *cflags, size_t count) +ppp_sync_receive(struct tty_struct *tty, const u8 *buf, const char *cflags, + size_t count) { struct syncppp *ap = sp_get(tty); unsigned long flags; @@ -655,8 +655,7 @@ ppp_sync_flush_output(struct syncppp *ap) * frame is considered to be in error and is tossed. */ static void -ppp_sync_input(struct syncppp *ap, const unsigned char *buf, - const char *flags, int count) +ppp_sync_input(struct syncppp *ap, const u8 *buf, const char *flags, int count) { struct sk_buff *skb; unsigned char *p; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 39450bf748a5..7bfa90724e7b 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -685,7 +685,7 @@ static void sl_setup(struct net_device *dev) * in parallel */ -static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, +static void slip_receive_buf(struct tty_struct *tty, const u8 *cp, const char *fp, size_t count) { struct slip *sl = tty->disc_data; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 2f85877b8ba1..86d89bbbaa16 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3489,7 +3489,7 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) gsm->tty = NULL; } -static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, +static void gsmld_receive_buf(struct tty_struct *tty, const u8 *cp, const char *fp, size_t count) { struct gsm_mux *gsm = tty->disc_data; diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index ce3c779f5c03..c86be060baed 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -369,7 +369,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) * Called by tty low level driver when receive data is available. Data is * interpreted as one HDLC frame. */ -static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, +static void n_hdlc_tty_receive(struct tty_struct *tty, const u8 *data, const char *flags, size_t count) { register struct n_hdlc *n_hdlc = tty->disc_data; diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index ee9b20dcbce6..d770007e5215 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1479,7 +1479,7 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag) } /* Caller must ensure count > 0 */ -static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const unsigned char *cp, +static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const u8 *cp, const unsigned char *fp, size_t count) { struct n_tty_data *ldata = tty->disc_data; @@ -1500,8 +1500,8 @@ static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const unsigned cha } static void -n_tty_receive_buf_real_raw(const struct tty_struct *tty, - const unsigned char *cp, int count) +n_tty_receive_buf_real_raw(const struct tty_struct *tty, const u8 *cp, + int count) { struct n_tty_data *ldata = tty->disc_data; size_t n, head; @@ -1520,7 +1520,7 @@ n_tty_receive_buf_real_raw(const struct tty_struct *tty, } static void -n_tty_receive_buf_raw(struct tty_struct *tty, const unsigned char *cp, +n_tty_receive_buf_raw(struct tty_struct *tty, const u8 *cp, const char *fp, int count) { struct n_tty_data *ldata = tty->disc_data; @@ -1537,7 +1537,7 @@ n_tty_receive_buf_raw(struct tty_struct *tty, const unsigned char *cp, } static void -n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp, +n_tty_receive_buf_closing(struct tty_struct *tty, const u8 *cp, const char *fp, int count, bool lookahead_done) { char flag = TTY_NORMAL; @@ -1550,14 +1550,15 @@ n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp, } } -static void n_tty_receive_buf_standard(struct tty_struct *tty, - const unsigned char *cp, const char *fp, int count, bool lookahead_done) +static void n_tty_receive_buf_standard(struct tty_struct *tty, const u8 *cp, + const char *fp, int count, + bool lookahead_done) { struct n_tty_data *ldata = tty->disc_data; char flag = TTY_NORMAL; while (count--) { - unsigned char c = *cp++; + u8 c = *cp++; if (fp) flag = *fp++; @@ -1588,7 +1589,7 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, } } -static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, +static void __receive_buf(struct tty_struct *tty, const u8 *cp, const char *fp, int count) { struct n_tty_data *ldata = tty->disc_data; @@ -1663,7 +1664,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, * publishes commit_head or canon_head */ static size_t -n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, +n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const char *fp, int count, int flow) { struct n_tty_data *ldata = tty->disc_data; @@ -1744,15 +1745,14 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, return rcvd; } -static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, +static void n_tty_receive_buf(struct tty_struct *tty, const u8 *cp, const char *fp, size_t count) { n_tty_receive_buf_common(tty, cp, fp, count, 0); } -static size_t n_tty_receive_buf2(struct tty_struct *tty, - const unsigned char *cp, const char *fp, - size_t count) +static size_t n_tty_receive_buf2(struct tty_struct *tty, const u8 *cp, + const char *fp, size_t count) { return n_tty_receive_buf_common(tty, cp, fp, count, 1); } diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 2751ac3946e7..e31cd9f281de 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -115,6 +115,6 @@ static inline void tty_audit_tiocsti(const struct tty_struct *tty, char ch) ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); int tty_insert_flip_string_and_push_buffer(struct tty_port *port, - const unsigned char *chars, size_t cnt); + const u8 *chars, size_t cnt); #endif diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 56f5732ce47f..9db42e6ed45b 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -316,8 +316,8 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); * * Returns: the number added. */ -int tty_insert_flip_string_fixed_flag(struct tty_port *port, - const unsigned char *chars, char flag, size_t size) +int tty_insert_flip_string_fixed_flag(struct tty_port *port, const u8 *chars, + char flag, size_t size) { int copied = 0; bool flags = flag != TTY_NORMAL; @@ -355,8 +355,8 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); * * Returns: the number added. */ -int tty_insert_flip_string_flags(struct tty_port *port, - const unsigned char *chars, const char *flags, size_t size) +int tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, + const char *flags, size_t size) { int copied = 0; @@ -390,7 +390,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); * Queue a single byte @ch to the tty buffering, with an optional flag. This is * the slow path of tty_insert_flip_char(). */ -int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) +int __tty_insert_flip_char(struct tty_port *port, u8 ch, char flag) { struct tty_buffer *tb; bool flags = flag != TTY_NORMAL; @@ -421,8 +421,7 @@ EXPORT_SYMBOL(__tty_insert_flip_char); * Returns: the length available and buffer pointer (@chars) to the space which * is now allocated and accounted for as ready for normal characters. */ -int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, - size_t size) +int tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size) { int space = __tty_buffer_request_room(port, size, false); @@ -450,8 +449,8 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); * * Returns: the number of bytes processed. */ -size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, - const char *f, size_t count) +size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const u8 *p, const char *f, + size_t count) { if (ld->ops->receive_buf2) count = ld->ops->receive_buf2(ld->tty, p, f, count); @@ -489,7 +488,7 @@ static void lookahead_bufs(struct tty_port *port, struct tty_buffer *head) } if (port->client_ops->lookahead_buf) { - unsigned char *p, *f = NULL; + u8 *p, *f = NULL; p = char_buf_ptr(head, head->lookahead); if (head->flags) @@ -620,7 +619,7 @@ EXPORT_SYMBOL(tty_flip_buffer_push); * Returns: the number added. */ int tty_insert_flip_string_and_push_buffer(struct tty_port *port, - const unsigned char *chars, size_t size) + const u8 *chars, size_t size) { struct tty_bufhead *buf = &port->buf; unsigned long flags; diff --git a/include/linux/tty_buffer.h b/include/linux/tty_buffer.h index 6ceb2789e6c8..6f2966b15093 100644 --- a/include/linux/tty_buffer.h +++ b/include/linux/tty_buffer.h @@ -22,9 +22,9 @@ struct tty_buffer { unsigned long data[]; }; -static inline unsigned char *char_buf_ptr(struct tty_buffer *b, int ofs) +static inline u8 *char_buf_ptr(struct tty_buffer *b, int ofs) { - return ((unsigned char *)b->data) + ofs; + return ((u8 *)b->data) + ofs; } static inline char *flag_buf_ptr(struct tty_buffer *b, int ofs) diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index 09c4dbcd0025..a0fcffeaaa25 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -10,17 +10,15 @@ struct tty_ldisc; int tty_buffer_set_limit(struct tty_port *port, int limit); unsigned int tty_buffer_space_avail(struct tty_port *port); int tty_buffer_request_room(struct tty_port *port, size_t size); -int tty_insert_flip_string_flags(struct tty_port *port, - const unsigned char *chars, const char *flags, size_t size); -int tty_insert_flip_string_fixed_flag(struct tty_port *port, - const unsigned char *chars, char flag, size_t size); -int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, - size_t size); +int tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, + const char *flags, size_t size); +int tty_insert_flip_string_fixed_flag(struct tty_port *port, const u8 *chars, + char flag, size_t size); +int tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size); void tty_flip_buffer_push(struct tty_port *port); -int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag); +int __tty_insert_flip_char(struct tty_port *port, u8 ch, char flag); -static inline int tty_insert_flip_char(struct tty_port *port, - unsigned char ch, char flag) +static inline int tty_insert_flip_char(struct tty_port *port, u8 ch, char flag) { struct tty_buffer *tb = port->buf.tail; int change; @@ -36,13 +34,13 @@ static inline int tty_insert_flip_char(struct tty_port *port, } static inline int tty_insert_flip_string(struct tty_port *port, - const unsigned char *chars, size_t size) + const u8 *chars, size_t size) { return tty_insert_flip_string_fixed_flag(port, chars, TTY_NORMAL, size); } -size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, - const char *f, size_t count); +size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const u8 *p, const char *f, + size_t count); void tty_buffer_lock_exclusive(struct tty_port *port); void tty_buffer_unlock_exclusive(struct tty_port *port); diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index f88529e6a783..5551c4400e59 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -161,8 +161,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * * Optional. Can sleep. * - * @receive_buf: [DRV] ``void ()(struct tty_struct *tty, - * const unsigned char *cp, const char *fp, size_t count)`` + * @receive_buf: [DRV] ``void ()(struct tty_struct *tty, const u8 *cp, + * const char *fp, size_t count)`` * * This function is called by the low-level tty driver to send characters * received by the hardware to the line discpline for processing. @cp is @@ -191,8 +191,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * * Optional. * - * @receive_buf2: [DRV] ``ssize_t ()(struct tty_struct *tty, - * const unsigned char *cp, const char *fp, size_t count)`` + * @receive_buf2: [DRV] ``ssize_t ()(struct tty_struct *tty, const u8 *cp, + * const char *fp, size_t count)`` * * This function is called by the low-level tty driver to send characters * received by the hardware to the line discpline for processing. @cp is a @@ -204,8 +204,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * * Optional. * - * @lookahead_buf: [DRV] ``void ()(struct tty_struct *tty, - * const unsigned char *cp, const char *fp, size_t count)`` + * @lookahead_buf: [DRV] ``void ()(struct tty_struct *tty, const u8 *cp, + * const char *fp, size_t count)`` * * This function is called by the low-level tty driver for characters * not eaten by ->receive_buf() or ->receive_buf2(). It is useful for @@ -255,13 +255,13 @@ struct tty_ldisc_ops { /* * The following routines are called from below. */ - void (*receive_buf)(struct tty_struct *tty, const unsigned char *cp, + void (*receive_buf)(struct tty_struct *tty, const u8 *cp, const char *fp, size_t count); void (*write_wakeup)(struct tty_struct *tty); void (*dcd_change)(struct tty_struct *tty, bool active); - size_t (*receive_buf2)(struct tty_struct *tty, const unsigned char *cp, + size_t (*receive_buf2)(struct tty_struct *tty, const u8 *cp, const char *fp, size_t count); - void (*lookahead_buf)(struct tty_struct *tty, const unsigned char *cp, + void (*lookahead_buf)(struct tty_struct *tty, const u8 *cp, const unsigned char *fp, size_t count); struct module *owner; diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 42cc863cbd53..6d4938e3cbad 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -258,8 +258,8 @@ static void v253_hangup(struct tty_struct *tty) } /* Line discipline .receive_buf() */ -static void v253_receive(struct tty_struct *tty, const unsigned char *cp, - const char *fp, size_t count) +static void v253_receive(struct tty_struct *tty, const u8 *cp, const char *fp, + size_t count) { struct snd_soc_component *component = tty->disc_data; struct cx20442_priv *cx20442; diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index 1028b5efcfff..371943350fdf 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -336,7 +336,7 @@ static void cx81801_hangup(struct tty_struct *tty) } /* Line discipline .receive_buf() */ -static void cx81801_receive(struct tty_struct *tty, const unsigned char *cp, +static void cx81801_receive(struct tty_struct *tty, const u8 *cp, const char *fp, int count) { struct snd_soc_component *component = tty->disc_data; -- cgit v1.2.3 From 892bc209f250fb49ddca31c74d2c7b1126a7a61a Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:51 +0200 Subject: tty: use u8 for flags This makes all those 'char's an explicit 'u8'. This is part of the continuing unification of chars and flags to be consistent u8. This approaches tty_port_default_receive_buf(). Note that we do not change signedness as we compile with -funsigned-char. Signed-off-by: "Jiri Slaby (SUSE)" Cc: William Hubbs Cc: Chris Brannon Cc: Kirk Reiser Cc: Samuel Thibault Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: Dmitry Torokhov Cc: Arnd Bergmann Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Max Staudt Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: Dario Binacchi Cc: Andreas Koensgen Cc: Jeremy Kerr Cc: Matt Johnston Cc: Krzysztof Kozlowski Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Acked-by: Mark Brown Link: https://lore.kernel.org/r/20230810091510.13006-18-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 2 +- drivers/bluetooth/hci_ldisc.c | 2 +- drivers/input/serio/serport.c | 2 +- drivers/misc/ti-st/st_core.c | 2 +- drivers/net/caif/caif_serial.c | 2 +- drivers/net/can/can327.c | 2 +- drivers/net/can/slcan/slcan-core.c | 2 +- drivers/net/hamradio/6pack.c | 2 +- drivers/net/hamradio/mkiss.c | 2 +- drivers/net/mctp/mctp-serial.c | 2 +- drivers/net/ppp/ppp_async.c | 7 +++---- drivers/net/ppp/ppp_synctty.c | 6 +++--- drivers/net/slip/slip.c | 4 ++-- drivers/tty/n_gsm.c | 2 +- drivers/tty/n_hdlc.c | 2 +- drivers/tty/n_tty.c | 28 ++++++++++++++-------------- drivers/tty/tty_buffer.c | 8 ++++---- drivers/tty/tty_port.c | 2 +- include/linux/tty_buffer.h | 4 ++-- include/linux/tty_flip.h | 10 +++++----- include/linux/tty_ldisc.h | 12 ++++++------ net/nfc/nci/uart.c | 2 +- sound/soc/codecs/cx20442.c | 2 +- 23 files changed, 54 insertions(+), 55 deletions(-) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index dd683a079c08..4c0a6e1f019d 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -72,7 +72,7 @@ static void spk_ttyio_ldisc_close(struct tty_struct *tty) } static size_t spk_ttyio_receive_buf2(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { struct spk_ldisc_data *ldisc_data = tty->disc_data; struct spk_synth *synth = ldisc_data->synth; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 32bef61c5901..b41071282ce5 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -599,7 +599,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) * Return Value: None */ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, - const char *flags, size_t count) + const u8 *flags, size_t count) { struct hci_uart *hu = tty->disc_data; diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 8bf79d39964d..5ce8d9f10f3e 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -115,7 +115,7 @@ static void serport_ldisc_close(struct tty_struct *tty) */ static void serport_ldisc_receive(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { struct serport *serport = tty->disc_data; unsigned long flags; diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 0ce4e46ff161..4467c5b94ae8 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -792,7 +792,7 @@ static void st_tty_close(struct tty_struct *tty) } static void st_tty_receive(struct tty_struct *tty, const u8 *data, - const char *tty_flags, size_t count) + const u8 *tty_flags, size_t count) { #ifdef VERBOSE print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index feda04dbe837..ed3a589def6b 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -159,7 +159,7 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size) #endif static void ldisc_receive(struct tty_struct *tty, const u8 *data, - const char *flags, size_t count) + const u8 *flags, size_t count) { struct sk_buff *skb = NULL; struct ser_device *ser; diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c index a054f5fd0d43..24af63961030 100644 --- a/drivers/net/can/can327.c +++ b/drivers/net/can/can327.c @@ -886,7 +886,7 @@ static bool can327_is_valid_rx_char(u8 c) * functions may be called in parallel. */ static void can327_ldisc_rx(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { struct can327 *elm = tty->disc_data; size_t first_new_char_idx; diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c index fe5671dbeb77..24c6622d36bd 100644 --- a/drivers/net/can/slcan/slcan-core.c +++ b/drivers/net/can/slcan/slcan-core.c @@ -775,7 +775,7 @@ static const struct net_device_ops slcan_netdev_ops = { * in parallel */ static void slcan_receive_buf(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { struct slcan *sl = tty->disc_data; diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 9a1f2a3f3b4f..6ed38a3cdd73 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -428,7 +428,7 @@ out: * and sent on to some IP layer for further processing. */ static void sixpack_receive_buf(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { struct sixpack *sp; int count1; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 26dbcf49bfa6..5f38a002bd9e 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -875,7 +875,7 @@ static int mkiss_ioctl(struct tty_struct *tty, unsigned int cmd, * and sent on to the AX.25 layer for further processing. */ static void mkiss_receive_buf(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { struct mkiss *ax = mkiss_get(tty); diff --git a/drivers/net/mctp/mctp-serial.c b/drivers/net/mctp/mctp-serial.c index 5f809a18d308..5bf6fdff701c 100644 --- a/drivers/net/mctp/mctp-serial.c +++ b/drivers/net/mctp/mctp-serial.c @@ -391,7 +391,7 @@ static void mctp_serial_push(struct mctp_serial *dev, unsigned char c) } static void mctp_serial_tty_receive_buf(struct tty_struct *tty, const u8 *c, - const char *f, size_t len) + const u8 *f, size_t len) { struct mctp_serial *dev = tty->disc_data; int i; diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index a661ccdea6ab..cfd5cb609d99 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -98,7 +98,7 @@ static int ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb); static int ppp_async_push(struct asyncppp *ap); static void ppp_async_flush_output(struct asyncppp *ap); static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - const char *flags, int count); + const u8 *flags, int count); static int ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg); static void ppp_async_process(struct tasklet_struct *t); @@ -330,7 +330,7 @@ ppp_asynctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) /* May sleep, don't call from interrupt level or with interrupts disabled */ static void -ppp_asynctty_receive(struct tty_struct *tty, const u8 *buf, const char *cflags, +ppp_asynctty_receive(struct tty_struct *tty, const u8 *buf, const u8 *cflags, size_t count) { struct asyncppp *ap = ap_get(tty); @@ -819,8 +819,7 @@ process_input_packet(struct asyncppp *ap) other ldisc functions but will not be re-entered */ static void -ppp_async_input(struct asyncppp *ap, const u8 *buf, const char *flags, - int count) +ppp_async_input(struct asyncppp *ap, const u8 *buf, const u8 *flags, int count) { struct sk_buff *skb; int c, i, j, n, s, f; diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 2a5cf6be9591..164c9053f73b 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -93,7 +93,7 @@ static int ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, static void ppp_sync_process(struct tasklet_struct *t); static int ppp_sync_push(struct syncppp *ap); static void ppp_sync_flush_output(struct syncppp *ap); -static void ppp_sync_input(struct syncppp *ap, const u8 *buf, const char *flags, +static void ppp_sync_input(struct syncppp *ap, const u8 *buf, const u8 *flags, int count); static const struct ppp_channel_ops sync_ops = { @@ -323,7 +323,7 @@ ppp_synctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) /* May sleep, don't call from interrupt level or with interrupts disabled */ static void -ppp_sync_receive(struct tty_struct *tty, const u8 *buf, const char *cflags, +ppp_sync_receive(struct tty_struct *tty, const u8 *buf, const u8 *cflags, size_t count) { struct syncppp *ap = sp_get(tty); @@ -655,7 +655,7 @@ ppp_sync_flush_output(struct syncppp *ap) * frame is considered to be in error and is tossed. */ static void -ppp_sync_input(struct syncppp *ap, const u8 *buf, const char *flags, int count) +ppp_sync_input(struct syncppp *ap, const u8 *buf, const u8 *flags, int count) { struct sk_buff *skb; unsigned char *p; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index 7bfa90724e7b..e4280e37fec9 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -685,8 +685,8 @@ static void sl_setup(struct net_device *dev) * in parallel */ -static void slip_receive_buf(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) +static void slip_receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp, + size_t count) { struct slip *sl = tty->disc_data; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 86d89bbbaa16..a3bd1fc52aed 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3490,7 +3490,7 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) } static void gsmld_receive_buf(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { struct gsm_mux *gsm = tty->disc_data; char flags = TTY_NORMAL; diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index c86be060baed..9be0932d07e0 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -370,7 +370,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) * interpreted as one HDLC frame. */ static void n_hdlc_tty_receive(struct tty_struct *tty, const u8 *data, - const char *flags, size_t count) + const u8 *flags, size_t count) { register struct n_hdlc *n_hdlc = tty->disc_data; register struct n_hdlc_buf *buf; diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d770007e5215..1053b2adb04c 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1480,7 +1480,7 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag) /* Caller must ensure count > 0 */ static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const u8 *cp, - const unsigned char *fp, size_t count) + const u8 *fp, size_t count) { struct n_tty_data *ldata = tty->disc_data; unsigned char flag = TTY_NORMAL; @@ -1520,11 +1520,11 @@ n_tty_receive_buf_real_raw(const struct tty_struct *tty, const u8 *cp, } static void -n_tty_receive_buf_raw(struct tty_struct *tty, const u8 *cp, - const char *fp, int count) +n_tty_receive_buf_raw(struct tty_struct *tty, const u8 *cp, const u8 *fp, + int count) { struct n_tty_data *ldata = tty->disc_data; - char flag = TTY_NORMAL; + u8 flag = TTY_NORMAL; while (count--) { if (fp) @@ -1537,8 +1537,8 @@ n_tty_receive_buf_raw(struct tty_struct *tty, const u8 *cp, } static void -n_tty_receive_buf_closing(struct tty_struct *tty, const u8 *cp, - const char *fp, int count, bool lookahead_done) +n_tty_receive_buf_closing(struct tty_struct *tty, const u8 *cp, const u8 *fp, + int count, bool lookahead_done) { char flag = TTY_NORMAL; @@ -1551,11 +1551,11 @@ n_tty_receive_buf_closing(struct tty_struct *tty, const u8 *cp, } static void n_tty_receive_buf_standard(struct tty_struct *tty, const u8 *cp, - const char *fp, int count, + const u8 *fp, int count, bool lookahead_done) { struct n_tty_data *ldata = tty->disc_data; - char flag = TTY_NORMAL; + u8 flag = TTY_NORMAL; while (count--) { u8 c = *cp++; @@ -1589,8 +1589,8 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, const u8 *cp, } } -static void __receive_buf(struct tty_struct *tty, const u8 *cp, - const char *fp, int count) +static void __receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp, + int count) { struct n_tty_data *ldata = tty->disc_data; bool preops = I_ISTRIP(tty) || (I_IUCLC(tty) && L_IEXTEN(tty)); @@ -1664,8 +1664,8 @@ static void __receive_buf(struct tty_struct *tty, const u8 *cp, * publishes commit_head or canon_head */ static size_t -n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, - const char *fp, int count, int flow) +n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const u8 *fp, + int count, int flow) { struct n_tty_data *ldata = tty->disc_data; size_t rcvd = 0; @@ -1746,13 +1746,13 @@ n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, } static void n_tty_receive_buf(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { n_tty_receive_buf_common(tty, cp, fp, count, 0); } static size_t n_tty_receive_buf2(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count) + const u8 *fp, size_t count) { return n_tty_receive_buf_common(tty, cp, fp, count, 1); } diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 9db42e6ed45b..684d099cbe11 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -317,7 +317,7 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); * Returns: the number added. */ int tty_insert_flip_string_fixed_flag(struct tty_port *port, const u8 *chars, - char flag, size_t size) + u8 flag, size_t size) { int copied = 0; bool flags = flag != TTY_NORMAL; @@ -356,7 +356,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); * Returns: the number added. */ int tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, - const char *flags, size_t size) + const u8 *flags, size_t size) { int copied = 0; @@ -390,7 +390,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); * Queue a single byte @ch to the tty buffering, with an optional flag. This is * the slow path of tty_insert_flip_char(). */ -int __tty_insert_flip_char(struct tty_port *port, u8 ch, char flag) +int __tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) { struct tty_buffer *tb; bool flags = flag != TTY_NORMAL; @@ -449,7 +449,7 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); * * Returns: the number of bytes processed. */ -size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const u8 *p, const char *f, +size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const u8 *p, const u8 *f, size_t count) { if (ld->ops->receive_buf2) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 7fd171b7c844..624d104bd145 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -34,7 +34,7 @@ static size_t tty_port_default_receive_buf(struct tty_port *port, const u8 *p, if (!ld) return 0; - count = tty_ldisc_receive_buf(ld, p, (char *)f, count); + count = tty_ldisc_receive_buf(ld, p, f, count); tty_ldisc_deref(ld); diff --git a/include/linux/tty_buffer.h b/include/linux/tty_buffer.h index 6f2966b15093..b11cc8c749d2 100644 --- a/include/linux/tty_buffer.h +++ b/include/linux/tty_buffer.h @@ -27,9 +27,9 @@ static inline u8 *char_buf_ptr(struct tty_buffer *b, int ofs) return ((u8 *)b->data) + ofs; } -static inline char *flag_buf_ptr(struct tty_buffer *b, int ofs) +static inline u8 *flag_buf_ptr(struct tty_buffer *b, int ofs) { - return (char *)char_buf_ptr(b, ofs) + b->size; + return char_buf_ptr(b, ofs) + b->size; } struct tty_bufhead { diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index a0fcffeaaa25..d33aed2172c7 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -11,14 +11,14 @@ int tty_buffer_set_limit(struct tty_port *port, int limit); unsigned int tty_buffer_space_avail(struct tty_port *port); int tty_buffer_request_room(struct tty_port *port, size_t size); int tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, - const char *flags, size_t size); + const u8 *flags, size_t size); int tty_insert_flip_string_fixed_flag(struct tty_port *port, const u8 *chars, - char flag, size_t size); + u8 flag, size_t size); int tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size); void tty_flip_buffer_push(struct tty_port *port); -int __tty_insert_flip_char(struct tty_port *port, u8 ch, char flag); +int __tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag); -static inline int tty_insert_flip_char(struct tty_port *port, u8 ch, char flag) +static inline int tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) { struct tty_buffer *tb = port->buf.tail; int change; @@ -39,7 +39,7 @@ static inline int tty_insert_flip_string(struct tty_port *port, return tty_insert_flip_string_fixed_flag(port, chars, TTY_NORMAL, size); } -size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const u8 *p, const char *f, +size_t tty_ldisc_receive_buf(struct tty_ldisc *ld, const u8 *p, const u8 *f, size_t count); void tty_buffer_lock_exclusive(struct tty_port *port); diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 5551c4400e59..a661d7df5497 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -162,7 +162,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * Optional. Can sleep. * * @receive_buf: [DRV] ``void ()(struct tty_struct *tty, const u8 *cp, - * const char *fp, size_t count)`` + * const u8 *fp, size_t count)`` * * This function is called by the low-level tty driver to send characters * received by the hardware to the line discpline for processing. @cp is @@ -192,7 +192,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * Optional. * * @receive_buf2: [DRV] ``ssize_t ()(struct tty_struct *tty, const u8 *cp, - * const char *fp, size_t count)`` + * const u8 *fp, size_t count)`` * * This function is called by the low-level tty driver to send characters * received by the hardware to the line discpline for processing. @cp is a @@ -205,7 +205,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * Optional. * * @lookahead_buf: [DRV] ``void ()(struct tty_struct *tty, const u8 *cp, - * const char *fp, size_t count)`` + * const u8 *fp, size_t count)`` * * This function is called by the low-level tty driver for characters * not eaten by ->receive_buf() or ->receive_buf2(). It is useful for @@ -256,13 +256,13 @@ struct tty_ldisc_ops { * The following routines are called from below. */ void (*receive_buf)(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count); + const u8 *fp, size_t count); void (*write_wakeup)(struct tty_struct *tty); void (*dcd_change)(struct tty_struct *tty, bool active); size_t (*receive_buf2)(struct tty_struct *tty, const u8 *cp, - const char *fp, size_t count); + const u8 *fp, size_t count); void (*lookahead_buf)(struct tty_struct *tty, const u8 *cp, - const unsigned char *fp, size_t count); + const u8 *fp, size_t count); struct module *owner; }; diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index c957ca6d2f87..93775c540287 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -296,7 +296,7 @@ static int nci_uart_default_recv_buf(struct nci_uart *nu, const u8 *data, * Return Value: None */ static void nci_uart_tty_receive(struct tty_struct *tty, const u8 *data, - const char *flags, size_t count) + const u8 *flags, size_t count) { struct nci_uart *nu = tty->disc_data; diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 6d4938e3cbad..9d54141a0cd1 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -258,7 +258,7 @@ static void v253_hangup(struct tty_struct *tty) } /* Line discipline .receive_buf() */ -static void v253_receive(struct tty_struct *tty, const u8 *cp, const char *fp, +static void v253_receive(struct tty_struct *tty, const u8 *cp, const u8 *fp, size_t count) { struct snd_soc_component *component = tty->disc_data; -- cgit v1.2.3 From ead03e721f410d83825835b5abd8e84fcb4305fa Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:52 +0200 Subject: misc: ti-st: make st_recv() conforming to tty_ldisc_ops::receive_buf() That is change data type to u8 and count to unsigned int. And propagate to both hooks (st_kim_recv() and kim_int_recv()). Signed-off-by: "Jiri Slaby (SUSE)" Cc: Arnd Bergmann Link: https://lore.kernel.org/r/20230810091510.13006-19-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 7 +++---- drivers/misc/ti-st/st_kim.c | 6 +++--- include/linux/ti_wilink_st.h | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 4467c5b94ae8..c1a134bd8ba7 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -21,7 +21,7 @@ * st_kim_recv during registration to receive fw download responses * st_int_recv after registration to receive proto stack responses */ -static void (*st_recv) (void *, const unsigned char *, long); +static void (*st_recv)(void *disc_data, const u8 *ptr, size_t count); /********************************************************************/ static void add_channel_to_table(struct st_data_s *st_gdata, @@ -223,8 +223,7 @@ static inline void st_wakeup_ack(struct st_data_s *st_gdata, * HCI-Events, ACL, SCO, 4 types of HCI-LL PM packets * CH-8 packets from FM, CH-9 packets from GPS cores. */ -static void st_int_recv(void *disc_data, - const unsigned char *ptr, long count) +static void st_int_recv(void *disc_data, const u8 *ptr, size_t count) { struct st_proto_s *proto; unsigned short payload_len = 0; @@ -239,7 +238,7 @@ static void st_int_recv(void *disc_data, return; } - pr_debug("count %ld rx_state %ld" + pr_debug("count %zu rx_state %ld" "rx_count %ld", count, st_gdata->rx_state, st_gdata->rx_count); diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 5431a89924aa..fe682e0553b2 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -127,8 +127,8 @@ static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len) * have been observed to come in bursts of different * tty_receive and hence the logic */ -static void kim_int_recv(struct kim_data_s *kim_gdata, - const unsigned char *ptr, long count) +static void kim_int_recv(struct kim_data_s *kim_gdata, const u8 *ptr, + size_t count) { int len = 0; unsigned char *plen; @@ -417,7 +417,7 @@ static long download_firmware(struct kim_data_s *kim_gdata) * 1. response to read local version * 2. during send/recv's of firmware download */ -void st_kim_recv(void *disc_data, const unsigned char *data, long count) +void st_kim_recv(void *disc_data, const u8 *data, size_t count) { struct st_data_s *st_gdata = (struct st_data_s *)disc_data; struct kim_data_s *kim_gdata = st_gdata->kim_data; diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h index 44a7f9169ac6..10642d4844f0 100644 --- a/include/linux/ti_wilink_st.h +++ b/include/linux/ti_wilink_st.h @@ -271,7 +271,7 @@ long st_kim_stop(void *); void st_kim_complete(void *); void kim_st_list_protocols(struct st_data_s *, void *); -void st_kim_recv(void *, const unsigned char *, long); +void st_kim_recv(void *disc_data, const u8 *data, size_t count); /* -- cgit v1.2.3 From 5db35be97cca6dd250df5c8144fcf7429ceb7f12 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:53 +0200 Subject: tty: make char_buf_ptr()/flag_buf_ptr()'s offset unsigned The offset is meant from the beginning of data, so unsigned. Make it as such for clarity. All struct tty_buffer's members should be unsigned too -- see the next patch. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-20-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- include/linux/tty_buffer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/tty_buffer.h b/include/linux/tty_buffer.h index b11cc8c749d2..391a875be20c 100644 --- a/include/linux/tty_buffer.h +++ b/include/linux/tty_buffer.h @@ -22,12 +22,12 @@ struct tty_buffer { unsigned long data[]; }; -static inline u8 *char_buf_ptr(struct tty_buffer *b, int ofs) +static inline u8 *char_buf_ptr(struct tty_buffer *b, unsigned int ofs) { return ((u8 *)b->data) + ofs; } -static inline u8 *flag_buf_ptr(struct tty_buffer *b, int ofs) +static inline u8 *flag_buf_ptr(struct tty_buffer *b, unsigned int ofs) { return char_buf_ptr(b, ofs) + b->size; } -- cgit v1.2.3 From b97552eb064d2257f4d5657eb6f375fd82a8a481 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:54 +0200 Subject: tty: tty_buffer: make all offsets unsigned All these are supposed/expected to be unsigned as they are either counts or offsets. So switch to unsigned for clarity. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-21-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- include/linux/tty_buffer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/tty_buffer.h b/include/linux/tty_buffer.h index 391a875be20c..e45cba81d0e9 100644 --- a/include/linux/tty_buffer.h +++ b/include/linux/tty_buffer.h @@ -12,11 +12,11 @@ struct tty_buffer { struct tty_buffer *next; struct llist_node free; }; - int used; - int size; - int commit; - int lookahead; /* Lazy update on recv, can become less than "read" */ - int read; + unsigned int used; + unsigned int size; + unsigned int commit; + unsigned int lookahead; /* Lazy update on recv, can become less than "read" */ + unsigned int read; bool flags; /* Data points here */ unsigned long data[]; -- cgit v1.2.3 From f47a4fd67f2a803f205db7a4136571c2bd487297 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:55 +0200 Subject: tty: don't pass write() to do_tty_write() write() passed to do_tty_write() is always ld->ops->write(). Instead, align with iterate_tty_read() and pass the whole ld instead. This makes the code easier to follow as it is clear what the write is. And also the function signature is more readable. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-22-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 54036a20a102..ea5041fbbf28 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -961,11 +961,8 @@ int tty_write_lock(struct tty_struct *tty, bool ndelay) * Split writes up in sane blocksizes to avoid * denial-of-service type attacks */ -static inline ssize_t do_tty_write( - ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t), - struct tty_struct *tty, - struct file *file, - struct iov_iter *from) +static inline ssize_t do_tty_write(struct tty_ldisc *ld, struct tty_struct *tty, + struct file *file, struct iov_iter *from) { size_t count = iov_iter_count(from); ssize_t ret, written = 0; @@ -1022,7 +1019,7 @@ static inline ssize_t do_tty_write( if (copy_from_iter(tty->write_buf, size, from) != size) break; - ret = write(tty, file, tty->write_buf, size); + ret = ld->ops->write(tty, file, tty->write_buf, size); if (ret <= 0) break; @@ -1093,7 +1090,7 @@ static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_ if (!ld->ops->write) ret = -EIO; else - ret = do_tty_write(ld->ops->write, tty, file, from); + ret = do_tty_write(ld, tty, file, from); tty_ldisc_deref(ld); return ret; } -- cgit v1.2.3 From a32a672dc5aaec1ccd246b3a27cee8a367b822c1 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:56 +0200 Subject: tty: rename and de-inline do_tty_write() Make do_tty_write()'s name sound similar to iterate_tty_read(). They both do similar things, so there is no reason for so distinct names. The new name is therefore iterate_tty_write(). Drop the unnedeed inline modifier too. Let the compiler decide. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-23-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ea5041fbbf28..846460c02c58 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -961,8 +961,8 @@ int tty_write_lock(struct tty_struct *tty, bool ndelay) * Split writes up in sane blocksizes to avoid * denial-of-service type attacks */ -static inline ssize_t do_tty_write(struct tty_ldisc *ld, struct tty_struct *tty, - struct file *file, struct iov_iter *from) +static ssize_t iterate_tty_write(struct tty_ldisc *ld, struct tty_struct *tty, + struct file *file, struct iov_iter *from) { size_t count = iov_iter_count(from); ssize_t ret, written = 0; @@ -1090,7 +1090,7 @@ static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_ if (!ld->ops->write) ret = -EIO; else - ret = do_tty_write(ld, tty, file, from); + ret = iterate_tty_write(ld, tty, file, from); tty_ldisc_deref(ld); return ret; } -- cgit v1.2.3 From ccc8dc00a24bb657b6a6f8adbfbb535365b4ba3d Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:57 +0200 Subject: tty: use min() in iterate_tty_write() It simplifies the code. The "price" is we have to unify 'chunk' to be size_t the same as 'count' is. But that change is actually correct. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-24-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 846460c02c58..0cf1277e260b 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -964,9 +964,8 @@ int tty_write_lock(struct tty_struct *tty, bool ndelay) static ssize_t iterate_tty_write(struct tty_ldisc *ld, struct tty_struct *tty, struct file *file, struct iov_iter *from) { - size_t count = iov_iter_count(from); + size_t chunk, count = iov_iter_count(from); ssize_t ret, written = 0; - unsigned int chunk; ret = tty_write_lock(tty, file->f_flags & O_NDELAY); if (ret < 0) @@ -1010,10 +1009,7 @@ static ssize_t iterate_tty_write(struct tty_ldisc *ld, struct tty_struct *tty, /* Do the write .. */ for (;;) { - size_t size = count; - - if (size > chunk) - size = chunk; + size_t size = min(chunk, count); ret = -EFAULT; if (copy_from_iter(tty->write_buf, size, from) != size) -- cgit v1.2.3 From 24b01c5d497ba422f34d381a693d0592e95ad5c3 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:58 +0200 Subject: tty: use ssize_t for iterate_tty_read() returned type tty_read() is supposed to return ssize_t. It takes the return value from iterate_tty_read(). That currently returns int. On the top of that, iterate_tty_write() already returns ssize_t. So switch iterate_tty_read() to ssize_t too, so that all three are consistent. This means 'i' in tty_read() changes its type too. And while changing that, rename this generic 'i' to more dedicated 'ret'. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-25-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 0cf1277e260b..e8248773e3f0 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -843,13 +843,13 @@ static void tty_update_time(struct tty_struct *tty, bool mtime) * data or clears the cookie. The cookie may be something that the * ldisc maintains state for and needs to free. */ -static int iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, - struct file *file, struct iov_iter *to) +static ssize_t iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, + struct file *file, struct iov_iter *to) { - int retval = 0; void *cookie = NULL; unsigned long offset = 0; char kernel_buf[64]; + ssize_t retval = 0; size_t count = iov_iter_count(to); do { @@ -912,11 +912,11 @@ static int iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, */ static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to) { - int i; struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); struct tty_struct *tty = file_tty(file); struct tty_ldisc *ld; + ssize_t ret; if (tty_paranoia_check(tty, inode, "tty_read")) return -EIO; @@ -929,15 +929,15 @@ static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to) ld = tty_ldisc_ref_wait(tty); if (!ld) return hung_up_tty_read(iocb, to); - i = -EIO; + ret = -EIO; if (ld->ops->read) - i = iterate_tty_read(ld, tty, file, to); + ret = iterate_tty_read(ld, tty, file, to); tty_ldisc_deref(ld); - if (i > 0) + if (ret > 0) tty_update_time(tty, false); - return i; + return ret; } void tty_write_unlock(struct tty_struct *tty) -- cgit v1.2.3 From e3afc5b0d708e2ef389b9c7acd45d1e4fd2cb304 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:14:59 +0200 Subject: tty: switch size and count types in iterate_tty_read() to size_t ld->ops->read() returns ssize_t. copy_to_iter() returns size_t. So switch the variables ('size' and 'copied', respectively) to the corresponding types. This allows for use of min() in the next patch. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-26-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e8248773e3f0..7cfa99fbbb62 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -850,10 +850,10 @@ static ssize_t iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, unsigned long offset = 0; char kernel_buf[64]; ssize_t retval = 0; - size_t count = iov_iter_count(to); + size_t copied, count = iov_iter_count(to); do { - int size, copied; + ssize_t size; size = count > sizeof(kernel_buf) ? sizeof(kernel_buf) : count; size = ld->ops->read(tty, file, kernel_buf, size, &cookie, offset); -- cgit v1.2.3 From 48a6ab8867eff61fa11d9e8f8e1c7327b135e689 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:00 +0200 Subject: tty: use min() for size computation in iterate_tty_read() The computation is more obvious with min(). Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-27-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 7cfa99fbbb62..4f21a21a1fd5 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -853,9 +853,8 @@ static ssize_t iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, size_t copied, count = iov_iter_count(to); do { - ssize_t size; + ssize_t size = min(count, sizeof(kernel_buf)); - size = count > sizeof(kernel_buf) ? sizeof(kernel_buf) : count; size = ld->ops->read(tty, file, kernel_buf, size, &cookie, offset); if (!size) break; -- cgit v1.2.3 From 69851e4ab8feeb369119a44ddca430c0ee15f0d8 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:01 +0200 Subject: tty: propagate u8 data to tty_operations::write() Data are now typed as u8. Propagate this change to tty_operations::write(). Signed-off-by: "Jiri Slaby (SUSE)" Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner Cc: Geert Uytterhoeven Cc: Richard Weinberger Cc: Anton Ivanov Cc: Johannes Berg Cc: Chris Zankel Cc: Max Filippov Cc: Arnd Bergmann Cc: Vaibhav Gupta Cc: Jens Taprogge Cc: Karsten Keil Cc: Scott Branden Cc: Ulf Hansson Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Alexander Gordeev Cc: Christian Borntraeger Cc: Sven Schnelle Cc: David Lin Cc: Johan Hovold Cc: Alex Elder Cc: Laurentiu Tudor Cc: Jiri Kosina Cc: David Sterba Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: Arnaud Pouliquen Cc: Oliver Neukum Cc: Mathias Nyman Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Link: https://lore.kernel.org/r/20230810091510.13006-28-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/srmcons.c | 3 +-- arch/m68k/emu/nfcon.c | 3 +-- arch/um/drivers/line.c | 2 +- arch/um/drivers/line.h | 3 +-- arch/xtensa/platforms/iss/console.c | 3 +-- drivers/char/ttyprintk.c | 5 ++--- drivers/ipack/devices/ipoctal.c | 6 ++---- drivers/isdn/capi/capi.c | 3 +-- drivers/misc/bcm-vk/bcm_vk_tty.c | 4 +--- drivers/mmc/core/sdio_uart.c | 3 +-- drivers/net/usb/hso.c | 3 +-- drivers/s390/char/con3215.c | 3 +-- drivers/s390/char/con3270.c | 3 +-- drivers/s390/char/sclp_tty.c | 2 +- drivers/s390/char/sclp_vt220.c | 2 +- drivers/staging/gdm724x/gdm_tty.c | 3 +-- drivers/staging/greybus/uart.c | 3 +-- drivers/tty/amiserial.c | 2 +- drivers/tty/ehv_bytechan.c | 3 +-- drivers/tty/goldfish.c | 6 ++---- drivers/tty/hvc/hvc_console.c | 2 +- drivers/tty/hvc/hvcs.c | 3 +-- drivers/tty/hvc/hvsi.c | 3 +-- drivers/tty/ipwireless/hardware.c | 2 +- drivers/tty/ipwireless/tty.c | 3 +-- drivers/tty/mips_ejtag_fdc.c | 4 ++-- drivers/tty/moxa.c | 8 +++----- drivers/tty/mxser.c | 2 +- drivers/tty/n_gsm.c | 3 +-- drivers/tty/nozomi.c | 5 ++--- drivers/tty/pty.c | 2 +- drivers/tty/serial/kgdb_nmi.c | 2 +- drivers/tty/serial/serial_core.c | 3 +-- drivers/tty/synclink_gt.c | 7 +++---- drivers/tty/ttynull.c | 3 +-- drivers/tty/vcc.c | 3 +-- drivers/tty/vt/vt.c | 4 ++-- drivers/usb/class/cdc-acm.c | 3 +-- drivers/usb/gadget/function/u_serial.c | 2 +- drivers/usb/host/xhci-dbgtty.c | 4 +--- drivers/usb/serial/usb-serial.c | 3 +-- include/linux/tty_driver.h | 3 +-- net/bluetooth/rfcomm/tty.c | 2 +- 43 files changed, 53 insertions(+), 88 deletions(-) diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 6dc952b0df4a..dea39008d93e 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -130,8 +130,7 @@ srmcons_do_write(struct tty_port *port, const char *buf, int count) } static int -srmcons_write(struct tty_struct *tty, - const unsigned char *buf, int count) +srmcons_write(struct tty_struct *tty, const u8 *buf, int count) { unsigned long flags; diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index 6fdc13610565..e7a21234b481 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c @@ -70,8 +70,7 @@ static void nfcon_tty_close(struct tty_struct *tty, struct file *filp) { } -static int nfcon_tty_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int nfcon_tty_write(struct tty_struct *tty, const u8 *buf, int count) { nfputs(buf, count); return count; diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 02b0befd6763..e5393b4ba9f8 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -184,7 +184,7 @@ void line_flush_chars(struct tty_struct *tty) line_flush_buffer(tty); } -int line_write(struct tty_struct *tty, const unsigned char *buf, int len) +int line_write(struct tty_struct *tty, const u8 *buf, int len) { struct line *line = tty->driver_data; unsigned long flags; diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index f15be75a3bf3..8354024b6b35 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h @@ -64,8 +64,7 @@ extern void line_cleanup(struct tty_struct *tty); extern void line_hangup(struct tty_struct *tty); extern int line_setup(char **conf, unsigned nlines, char **def, char *init, char *name); -extern int line_write(struct tty_struct *tty, const unsigned char *buf, - int len); +extern int line_write(struct tty_struct *tty, const u8 *buf, int len); extern unsigned int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); extern void line_flush_chars(struct tty_struct *tty); diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index b40b73809dd8..182ec57e2d5c 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -52,8 +52,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) } -static int rs_write(struct tty_struct * tty, - const unsigned char *buf, int count) +static int rs_write(struct tty_struct * tty, const u8 *buf, int count) { /* see drivers/char/serialX.c to reference original version */ diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index ed45d04905c2..4f3dd93f1fd8 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -51,7 +51,7 @@ static void tpk_flush(void) } } -static int tpk_printk(const unsigned char *buf, int count) +static int tpk_printk(const u8 *buf, int count) { int i; @@ -103,8 +103,7 @@ static void tpk_close(struct tty_struct *tty, struct file *filp) /* * TTY operations write function. */ -static int tpk_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int tpk_write(struct tty_struct *tty, const u8 *buf, int count) { struct ttyprintk_port *tpkp = tty->driver_data; unsigned long flags; diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index a01c15812b70..c3cf086e7e36 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -437,8 +437,7 @@ err_put_driver: } static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, - const unsigned char *buf, - int count) + const u8 *buf, int count) { unsigned long flags; int i; @@ -459,8 +458,7 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, return i; } -static int ipoctal_write_tty(struct tty_struct *tty, - const unsigned char *buf, int count) +static int ipoctal_write_tty(struct tty_struct *tty, const u8 *buf, int count) { struct ipoctal_channel *channel = tty->driver_data; unsigned int char_copied; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 45a4043c5042..cf6daf79c1a2 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1077,8 +1077,7 @@ static void capinc_tty_close(struct tty_struct *tty, struct file *filp) tty_port_close(&mp->port, tty, filp); } -static int capinc_tty_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int capinc_tty_write(struct tty_struct *tty, const u8 *buf, int count) { struct capiminor *mp = tty->driver_data; struct sk_buff *skb; diff --git a/drivers/misc/bcm-vk/bcm_vk_tty.c b/drivers/misc/bcm-vk/bcm_vk_tty.c index 6669625ba4c8..44851b607cce 100644 --- a/drivers/misc/bcm-vk/bcm_vk_tty.c +++ b/drivers/misc/bcm-vk/bcm_vk_tty.c @@ -186,9 +186,7 @@ static void bcm_vk_tty_doorbell(struct bcm_vk *vk, u32 db_val) VK_BAR0_REGSEG_DB_BASE + VK_BAR0_REGSEG_TTY_DB_OFFSET); } -static int bcm_vk_tty_write(struct tty_struct *tty, - const unsigned char *buffer, - int count) +static int bcm_vk_tty_write(struct tty_struct *tty, const u8 *buffer, int count) { int index; struct bcm_vk *vk; diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index aa659758563f..90d2fe00c0b9 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -760,8 +760,7 @@ static void sdio_uart_hangup(struct tty_struct *tty) tty_port_hangup(&port->port); } -static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int sdio_uart_write(struct tty_struct *tty, const u8 *buf, int count) { struct sdio_uart_port *port = tty->driver_data; int ret; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index ce1f6081d582..014a9d29bab5 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1322,8 +1322,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) } /* close the requested serial port */ -static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int hso_serial_write(struct tty_struct *tty, const u8 *buf, int count) { struct hso_serial *serial = tty->driver_data; int space, tx_bytes; diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index a1fef666c9b0..16b6f430dfd3 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -1021,8 +1021,7 @@ static unsigned int tty3215_write_room(struct tty_struct *tty) /* * String write routine for 3215 ttys */ -static int tty3215_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int tty3215_write(struct tty_struct *tty, const u8 *buf, int count) { handle_write(tty->driver_data, buf, count); return count; diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index d9983550062d..123524bff734 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -1803,8 +1803,7 @@ static void tty3270_do_write(struct tty3270 *tp, struct tty_struct *tty, /* * String write routine for 3270 ttys */ -static int tty3270_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int tty3270_write(struct tty_struct *tty, const u8 *buf, int count) { struct tty3270 *tp; diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 971fbb52740b..cc0f6a97124e 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -230,7 +230,7 @@ out: * routine will return the number of characters actually accepted for writing. */ static int -sclp_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) +sclp_tty_write(struct tty_struct *tty, const u8 *buf, int count) { if (sclp_tty_chars_count > 0) { sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0); diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index a32f34a1c6d2..44974d801c1e 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -463,7 +463,7 @@ out: * number of characters actually accepted for writing. */ static int -sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count) +sclp_vt220_write(struct tty_struct *tty, const u8 *buf, int count) { return __sclp_vt220_write(buf, count, 1, 0, 1); } diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index e1a84d6020f4..ae9978b73d9b 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -149,8 +149,7 @@ static void gdm_tty_send_complete(void *arg) tty_port_tty_wakeup(&gdm->port); } -static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, - int len) +static int gdm_tty_write(struct tty_struct *tty, const u8 *buf, int len) { struct gdm *gdm = tty->driver_data; int remain = len; diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 20a34599859f..97c7ddd0f53e 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -427,8 +427,7 @@ static void gb_tty_hangup(struct tty_struct *tty) tty_port_hangup(&gb_tty->port); } -static int gb_tty_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int gb_tty_write(struct tty_struct *tty, const u8 *buf, int count) { struct gb_tty *gb_tty = tty->driver_data; diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index c06ad0a0744b..1dd8b86f4a32 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -741,7 +741,7 @@ static void rs_flush_chars(struct tty_struct *tty) local_irq_restore(flags); } -static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) +static int rs_write(struct tty_struct * tty, const u8 *buf, int count) { int c, ret = 0; struct serial_state *info = tty->driver_data; diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 8595483f4697..de36347e2145 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -466,8 +466,7 @@ static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data) * ehv_bc_tty_write_room() will never lie, so the tty layer will never send us * too much data. */ -static int ehv_bc_tty_write(struct tty_struct *ttys, const unsigned char *s, - int count) +static int ehv_bc_tty_write(struct tty_struct *ttys, const u8 *s, int count) { struct ehv_bc_data *bc = ttys->driver_data; unsigned long flags; diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index d02de3f0326f..faa597ffbaf9 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -125,8 +125,7 @@ static void goldfish_tty_rw(struct goldfish_tty *qtty, } } -static void goldfish_tty_do_write(int line, const char *buf, - unsigned int count) +static void goldfish_tty_do_write(int line, const u8 *buf, unsigned int count) { struct goldfish_tty *qtty = &goldfish_ttys[line]; unsigned long address = (unsigned long)(void *)buf; @@ -186,8 +185,7 @@ static void goldfish_tty_hangup(struct tty_struct *tty) tty_port_hangup(tty->port); } -static int goldfish_tty_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int goldfish_tty_write(struct tty_struct *tty, const u8 *buf, int count) { goldfish_tty_do_write(tty->index, buf, count); return count; diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 10c10cfdf92a..4c60d15c7a6f 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -496,7 +496,7 @@ static int hvc_push(struct hvc_struct *hp) return n; } -static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count) +static int hvc_write(struct tty_struct *tty, const u8 *buf, int count) { struct hvc_struct *hp = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 1de1a09bf82d..2465d61b4e76 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1257,8 +1257,7 @@ static void hvcs_hangup(struct tty_struct * tty) * tty_hangup will allow hvcs_write time to complete execution before it * terminates our device. */ -static int hvcs_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int hvcs_write(struct tty_struct *tty, const u8 *buf, int count) { struct hvcs_struct *hvcsd = tty->driver_data; unsigned int unit_address; diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index c1b8a4fd8b1e..46dd62df2442 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -904,8 +904,7 @@ static unsigned int hvsi_chars_in_buffer(struct tty_struct *tty) return hp->n_outbuf; } -static int hvsi_write(struct tty_struct *tty, - const unsigned char *source, int count) +static int hvsi_write(struct tty_struct *tty, const u8 *source, int count) { struct hvsi_struct *hp = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index f5d3e68f5750..001ec318a918 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c @@ -1292,7 +1292,7 @@ static void *alloc_ctrl_packet(int header_size, } int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx, - const unsigned char *data, unsigned int length, + const u8 *data, unsigned int length, void (*callback) (void *cb, unsigned int length), void *callback_data) { diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 9edd5ae17580..cd43208c523c 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -186,8 +186,7 @@ static void ipw_write_packet_sent_callback(void *callback_data, tty->tx_bytes_queued -= packet_length; } -static int ipw_write(struct tty_struct *linux_tty, - const unsigned char *buf, int count) +static int ipw_write(struct tty_struct *linux_tty, const u8 *buf, int count) { struct ipw_tty *tty = linux_tty->driver_data; int room, ret; diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index e81701a66429..cf4ef0c38624 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -796,8 +796,8 @@ static void mips_ejtag_fdc_tty_hangup(struct tty_struct *tty) tty_port_hangup(tty->port); } -static int mips_ejtag_fdc_tty_write(struct tty_struct *tty, - const unsigned char *buf, int total) +static int mips_ejtag_fdc_tty_write(struct tty_struct *tty, const u8 *buf, + int total) { int count, block; struct mips_ejtag_fdc_tty_port *dport = tty->driver_data; diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 42fa4c878b2e..d94cf1be651b 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -487,7 +487,7 @@ module_param(ttymajor, int, 0); */ static int moxa_open(struct tty_struct *, struct file *); static void moxa_close(struct tty_struct *, struct file *); -static int moxa_write(struct tty_struct *, const unsigned char *, int); +static int moxa_write(struct tty_struct *, const u8 *, int); static unsigned int moxa_write_room(struct tty_struct *); static void moxa_flush_buffer(struct tty_struct *); static unsigned int moxa_chars_in_buffer(struct tty_struct *); @@ -1499,8 +1499,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) tty_port_close(&ch->port, tty, filp); } -static int moxa_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int moxa_write(struct tty_struct *tty, const u8 *buf, int count) { struct moxa_port *ch = tty->driver_data; unsigned long flags; @@ -2164,8 +2163,7 @@ static int MoxaPortLineStatus(struct moxa_port *port) return val; } -static int MoxaPortWriteData(struct tty_struct *tty, - const unsigned char *buffer, int len) +static int MoxaPortWriteData(struct tty_struct *tty, const u8 *buffer, int len) { struct moxa_port *port = tty->driver_data; void __iomem *baseAddr, *ofsAddr, *ofs; diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 10855e66fda1..8b4b8493fed5 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -901,7 +901,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) tty_port_close(tty->port, tty, filp); } -static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) +static int mxser_write(struct tty_struct *tty, const u8 *buf, int count) { struct mxser_port *info = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index a3bd1fc52aed..d167e36873fe 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -4256,8 +4256,7 @@ static void gsmtty_hangup(struct tty_struct *tty) gsm_dlci_begin_close(dlci); } -static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf, - int len) +static int gsmtty_write(struct tty_struct *tty, const u8 *buf, int len) { int sent; struct gsm_dlci *dlci = tty->driver_data; diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 0454c78deee6..b3756402f5d9 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1599,8 +1599,7 @@ static void ntty_hangup(struct tty_struct *tty) * called when the userspace process writes to the tty (/dev/noz*). * Data is inserted into a fifo, which is then read and transferred to the modem. */ -static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, - int count) +static int ntty_write(struct tty_struct *tty, const u8 *buffer, int count) { int rval = -EINVAL; struct nozomi *dc = get_dc_by_tty(tty); @@ -1610,7 +1609,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, if (!dc || !port) return -ENODEV; - rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); + rval = kfifo_in(&port->fifo_ul, buffer, count); spin_lock_irqsave(&dc->spin_mutex, flags); /* CTS is only valid on the modem channel */ diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 2b1c8ab99dba..335f5744f320 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -108,7 +108,7 @@ static void pty_unthrottle(struct tty_struct *tty) * the other side of the pty/tty pair. */ -static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) +static int pty_write(struct tty_struct *tty, const u8 *buf, int c) { struct tty_struct *to = tty->link; diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 55c3c9db7462..2a04d19d5ec0 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c @@ -304,7 +304,7 @@ static unsigned int kgdb_nmi_tty_write_room(struct tty_struct *tty) return 2048; } -static int kgdb_nmi_tty_write(struct tty_struct *tty, const unchar *buf, int c) +static int kgdb_nmi_tty_write(struct tty_struct *tty, const u8 *buf, int c) { int i; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index e31c9b6bd8ab..33df5b08d992 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -580,8 +580,7 @@ static void uart_flush_chars(struct tty_struct *tty) uart_start(tty); } -static int uart_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int uart_write(struct tty_struct *tty, const u8 *buf, int count) { struct uart_state *state = tty->driver_data; struct uart_port *port; diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 4c6366fe015c..c7cecea38ca8 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -431,7 +431,7 @@ static void tx_set_idle(struct slgt_info *info); static unsigned int tbuf_bytes(struct slgt_info *info); static void reset_tbufs(struct slgt_info *info); static void tdma_reset(struct slgt_info *info); -static bool tx_load(struct slgt_info *info, const char *buf, unsigned int count); +static bool tx_load(struct slgt_info *info, const u8 *buf, unsigned int count); static void get_gtsignals(struct slgt_info *info); static void set_gtsignals(struct slgt_info *info); @@ -745,8 +745,7 @@ static void update_tx_timer(struct slgt_info *info) } } -static int write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int write(struct tty_struct *tty, const u8 *buf, int count) { int ret = 0; struct slgt_info *info = tty->driver_data; @@ -4767,7 +4766,7 @@ static unsigned int tbuf_bytes(struct slgt_info *info) * load data into transmit DMA buffer ring and start transmitter if needed * return true if data accepted, otherwise false (buffers full) */ -static bool tx_load(struct slgt_info *info, const char *buf, unsigned int size) +static bool tx_load(struct slgt_info *info, const u8 *buf, unsigned int size) { unsigned short count; unsigned int i; diff --git a/drivers/tty/ttynull.c b/drivers/tty/ttynull.c index 1d4438472442..6b74ebaa0f2d 100644 --- a/drivers/tty/ttynull.c +++ b/drivers/tty/ttynull.c @@ -29,8 +29,7 @@ static void ttynull_hangup(struct tty_struct *tty) tty_port_hangup(&ttynull_port); } -static int ttynull_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int ttynull_write(struct tty_struct *tty, const u8 *buf, int count) { return count; } diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index 34ba6e54789a..c223879039b8 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -804,8 +804,7 @@ static void vcc_hangup(struct tty_struct *tty) tty_port_hangup(tty->port); } -static int vcc_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int vcc_write(struct tty_struct *tty, const u8 *buf, int count) { struct vcc_port *port; struct vio_vcc *pkt; diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index cf77011a8f4e..2f28612aee91 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2845,7 +2845,7 @@ static int vc_con_write_normal(struct vc_data *vc, int tc, int c, } /* acquires console_lock */ -static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) +static int do_con_write(struct tty_struct *tty, const u8 *buf, int count) { struct vc_draw_region draw = { .x = -1, @@ -3238,7 +3238,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) * /dev/ttyN handling */ -static int con_write(struct tty_struct *tty, const unsigned char *buf, int count) +static int con_write(struct tty_struct *tty, const u8 *buf, int count) { int retval; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 11da5fb284d0..913b07b30d33 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -789,8 +789,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) tty_port_close(&acm->port, tty, filp); } -static int acm_tty_write(struct tty_struct *tty, - const unsigned char *buf, int count) +static int acm_tty_write(struct tty_struct *tty, const u8 *buf, int count) { struct acm *acm = tty->driver_data; int stat; diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 1115396b46a0..1d08a1d8d3cd 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -734,7 +734,7 @@ exit: spin_unlock_irq(&port->port_lock); } -static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count) +static int gs_write(struct tty_struct *tty, const u8 *buf, int count) { struct gs_port *port = tty->driver_data; unsigned long flags; diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index d3acc0829ee5..f5f2d0e12e69 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -208,9 +208,7 @@ static void dbc_tty_close(struct tty_struct *tty, struct file *file) tty_port_close(&port->port, tty, file); } -static int dbc_tty_write(struct tty_struct *tty, - const unsigned char *buf, - int count) +static int dbc_tty_write(struct tty_struct *tty, const u8 *buf, int count) { struct dbc_port *port = tty->driver_data; unsigned long flags; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 7b4805c1004d..51f738ea3f77 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -361,8 +361,7 @@ static void serial_cleanup(struct tty_struct *tty) module_put(owner); } -static int serial_write(struct tty_struct *tty, const unsigned char *buf, - int count) +static int serial_write(struct tty_struct *tty, const u8 *buf, int count) { struct usb_serial_port *port = tty->driver_data; int retval = -ENODEV; diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index e00034118c7b..a7bd8060ac96 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -356,8 +356,7 @@ struct tty_operations { void (*close)(struct tty_struct * tty, struct file * filp); void (*shutdown)(struct tty_struct *tty); void (*cleanup)(struct tty_struct *tty); - int (*write)(struct tty_struct * tty, - const unsigned char *buf, int count); + int (*write)(struct tty_struct *tty, const u8 *buf, int count); int (*put_char)(struct tty_struct *tty, unsigned char ch); void (*flush_chars)(struct tty_struct *tty); unsigned int (*write_room)(struct tty_struct *tty); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index d73eec146529..3b5f8404dc84 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -779,7 +779,7 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) tty_port_close(&dev->port, tty, filp); } -static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) +static int rfcomm_tty_write(struct tty_struct *tty, const u8 *buf, int count) { struct rfcomm_dev *dev = tty->driver_data; struct rfcomm_dlc *dlc = dev->dlc; -- cgit v1.2.3 From dcaafbe6ee3b39f2df11a1352f85172f8ade17a5 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:02 +0200 Subject: tty: propagate u8 data to tty_operations::put_char() Data are now typed as u8. Propagate this change to tty_operations::put_char(). Signed-off-by: "Jiri Slaby (SUSE)" Cc: Geert Uytterhoeven Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Alexander Gordeev Cc: Christian Borntraeger Cc: Sven Schnelle Cc: Karsten Keil Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: Mathias Nyman Link: https://lore.kernel.org/r/20230810091510.13006-29-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/m68k/emu/nfcon.c | 4 ++-- drivers/isdn/capi/capi.c | 2 +- drivers/s390/char/con3215.c | 2 +- drivers/s390/char/con3270.c | 2 +- drivers/s390/char/sclp_tty.c | 6 +++--- drivers/s390/char/sclp_vt220.c | 2 +- drivers/tty/amiserial.c | 2 +- drivers/tty/mxser.c | 2 +- drivers/tty/serial/serial_core.c | 2 +- drivers/tty/synclink_gt.c | 4 ++-- drivers/tty/vt/vt.c | 2 +- drivers/usb/gadget/function/u_serial.c | 2 +- drivers/usb/host/xhci-dbgtty.c | 2 +- include/linux/tty_driver.h | 2 +- 14 files changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index e7a21234b481..87398f834e36 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c @@ -76,9 +76,9 @@ static int nfcon_tty_write(struct tty_struct *tty, const u8 *buf, int count) return count; } -static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch) +static int nfcon_tty_put_char(struct tty_struct *tty, u8 ch) { - char temp[2] = { ch, 0 }; + u8 temp[2] = { ch, 0 }; nf_call(stderr_id, virt_to_phys(temp)); return 1; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index cf6daf79c1a2..2f38e1cfe97a 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1111,7 +1111,7 @@ static int capinc_tty_write(struct tty_struct *tty, const u8 *buf, int count) return count; } -static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch) +static int capinc_tty_put_char(struct tty_struct *tty, u8 ch) { struct capiminor *mp = tty->driver_data; bool invoke_send = false; diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 16b6f430dfd3..8bbce6a4d7f5 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -1030,7 +1030,7 @@ static int tty3215_write(struct tty_struct *tty, const u8 *buf, int count) /* * Put character routine for 3215 ttys */ -static int tty3215_put_char(struct tty_struct *tty, unsigned char ch) +static int tty3215_put_char(struct tty_struct *tty, u8 ch) { struct raw3215_info *raw = tty->driver_data; diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 123524bff734..6374555a0937 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -1821,7 +1821,7 @@ static int tty3270_write(struct tty_struct *tty, const u8 *buf, int count) /* * Put single characters to the ttys character buffer */ -static int tty3270_put_char(struct tty_struct *tty, unsigned char ch) +static int tty3270_put_char(struct tty_struct *tty, u8 ch) { struct tty3270 *tp; diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index cc0f6a97124e..831a8c7cacc2 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -48,7 +48,7 @@ static struct sclp_buffer *sclp_ttybuf; static struct timer_list sclp_tty_timer; static struct tty_port sclp_port; -static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE]; +static u8 sclp_tty_chars[SCLP_TTY_BUF_SIZE]; static unsigned short int sclp_tty_chars_count; struct tty_driver *sclp_tty_driver; @@ -168,7 +168,7 @@ sclp_tty_timeout(struct timer_list *unused) /* * Write a string to the sclp tty. */ -static int sclp_tty_write_string(const unsigned char *str, int count, int may_fail) +static int sclp_tty_write_string(const u8 *str, int count, int may_fail) { unsigned long flags; void *page; @@ -250,7 +250,7 @@ sclp_tty_write(struct tty_struct *tty, const u8 *buf, int count) * sclp_write() without final '\n' - will be written. */ static int -sclp_tty_put_char(struct tty_struct *tty, unsigned char ch) +sclp_tty_put_char(struct tty_struct *tty, u8 ch) { sclp_tty_chars[sclp_tty_chars_count++] = ch; if (ch == '\n' || sclp_tty_chars_count >= SCLP_TTY_BUF_SIZE) { diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 44974d801c1e..e148350c1e2c 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -579,7 +579,7 @@ sclp_vt220_close(struct tty_struct *tty, struct file *filp) * done stuffing characters into the driver. */ static int -sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch) +sclp_vt220_put_char(struct tty_struct *tty, u8 ch) { return __sclp_vt220_write(&ch, 1, 0, 0, 1); } diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 1dd8b86f4a32..91cf294ec8c1 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -696,7 +696,7 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, local_irq_restore(flags); } -static int rs_put_char(struct tty_struct *tty, unsigned char ch) +static int rs_put_char(struct tty_struct *tty, u8 ch) { struct serial_state *info; unsigned long flags; diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 8b4b8493fed5..a5dfd08d4ea2 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -920,7 +920,7 @@ static int mxser_write(struct tty_struct *tty, const u8 *buf, int count) return written; } -static int mxser_put_char(struct tty_struct *tty, unsigned char ch) +static int mxser_put_char(struct tty_struct *tty, u8 ch) { struct mxser_port *info = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 33df5b08d992..d5b682ff20b3 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -551,7 +551,7 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) } EXPORT_SYMBOL(uart_get_divisor); -static int uart_put_char(struct tty_struct *tty, unsigned char c) +static int uart_put_char(struct tty_struct *tty, u8 c) { struct uart_state *state = tty->driver_data; struct uart_port *port; diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index c7cecea38ca8..0264e9f7699c 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -780,7 +780,7 @@ cleanup: return ret; } -static int put_char(struct tty_struct *tty, unsigned char ch) +static int put_char(struct tty_struct *tty, u8 ch) { struct slgt_info *info = tty->driver_data; unsigned long flags; @@ -788,7 +788,7 @@ static int put_char(struct tty_struct *tty, unsigned char ch) if (sanity_check(info, tty->name, "put_char")) return 0; - DBGINFO(("%s put_char(%d)\n", info->device_name, ch)); + DBGINFO(("%s put_char(%u)\n", info->device_name, ch)); if (!info->tx_buf) return 0; spin_lock_irqsave(&info->lock,flags); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 2f28612aee91..ea7c20d66acb 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3248,7 +3248,7 @@ static int con_write(struct tty_struct *tty, const u8 *buf, int count) return retval; } -static int con_put_char(struct tty_struct *tty, unsigned char ch) +static int con_put_char(struct tty_struct *tty, u8 ch) { return do_con_write(tty, &ch, 1); } diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 1d08a1d8d3cd..3e6b750aa4fc 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -753,7 +753,7 @@ static int gs_write(struct tty_struct *tty, const u8 *buf, int count) return count; } -static int gs_put_char(struct tty_struct *tty, unsigned char ch) +static int gs_put_char(struct tty_struct *tty, u8 ch) { struct gs_port *port = tty->driver_data; unsigned long flags; diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index f5f2d0e12e69..5b82bdd82ba9 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -222,7 +222,7 @@ static int dbc_tty_write(struct tty_struct *tty, const u8 *buf, int count) return count; } -static int dbc_tty_put_char(struct tty_struct *tty, unsigned char ch) +static int dbc_tty_put_char(struct tty_struct *tty, u8 ch) { struct dbc_port *port = tty->driver_data; unsigned long flags; diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index a7bd8060ac96..c5299d952e59 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -357,7 +357,7 @@ struct tty_operations { void (*shutdown)(struct tty_struct *tty); void (*cleanup)(struct tty_struct *tty); int (*write)(struct tty_struct *tty, const u8 *buf, int count); - int (*put_char)(struct tty_struct *tty, unsigned char ch); + int (*put_char)(struct tty_struct *tty, u8 ch); void (*flush_chars)(struct tty_struct *tty); unsigned int (*write_room)(struct tty_struct *tty); unsigned int (*chars_in_buffer)(struct tty_struct *tty); -- cgit v1.2.3 From 95713967ba52389f7cea75704d0cf048080ec218 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:03 +0200 Subject: tty: make tty_operations::write()'s count size_t Unify with the rest of the code. Use size_t for counts and ssize_t for retval. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-30-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/srmcons.c | 4 ++-- arch/m68k/emu/nfcon.c | 3 ++- arch/um/drivers/line.c | 2 +- arch/um/drivers/line.h | 2 +- arch/xtensa/platforms/iss/console.c | 2 +- drivers/char/ttyprintk.c | 2 +- drivers/ipack/devices/ipoctal.c | 3 ++- drivers/isdn/capi/capi.c | 5 +++-- drivers/misc/bcm-vk/bcm_vk_tty.c | 3 ++- drivers/mmc/core/sdio_uart.c | 3 ++- drivers/net/usb/hso.c | 3 ++- drivers/s390/char/con3215.c | 3 ++- drivers/s390/char/con3270.c | 3 ++- drivers/s390/char/sclp_tty.c | 4 ++-- drivers/s390/char/sclp_vt220.c | 4 ++-- drivers/staging/gdm724x/gdm_tty.c | 2 +- drivers/staging/greybus/uart.c | 2 +- drivers/tty/amiserial.c | 2 +- drivers/tty/ehv_bytechan.c | 3 ++- drivers/tty/goldfish.c | 3 ++- drivers/tty/hvc/hvc_console.c | 2 +- drivers/tty/hvc/hvcs.c | 5 +++-- drivers/tty/hvc/hvsi.c | 3 ++- drivers/tty/ipwireless/tty.c | 3 ++- drivers/tty/mips_ejtag_fdc.c | 6 +++--- drivers/tty/moxa.c | 4 ++-- drivers/tty/mxser.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/tty/nozomi.c | 3 ++- drivers/tty/pty.c | 2 +- drivers/tty/rpmsg_tty.c | 5 +++-- drivers/tty/serial/kgdb_nmi.c | 3 ++- drivers/tty/serial/serial_core.c | 2 +- drivers/tty/synclink_gt.c | 4 ++-- drivers/tty/ttynull.c | 3 ++- drivers/tty/vcc.c | 5 +++-- drivers/tty/vt/vt.c | 2 +- drivers/usb/class/cdc-acm.c | 7 ++++--- drivers/usb/gadget/function/u_serial.c | 4 ++-- drivers/usb/host/xhci-dbgtty.c | 3 ++- drivers/usb/serial/usb-serial.c | 4 ++-- include/linux/tty_driver.h | 6 +++--- net/bluetooth/rfcomm/tty.c | 5 +++-- 43 files changed, 82 insertions(+), 61 deletions(-) diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index dea39008d93e..d6139dbae4ac 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -129,8 +129,8 @@ srmcons_do_write(struct tty_port *port, const char *buf, int count) return count; } -static int -srmcons_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t +srmcons_write(struct tty_struct *tty, const u8 *buf, size_t count) { unsigned long flags; diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index 87398f834e36..3a74d493eb3e 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c @@ -70,7 +70,8 @@ static void nfcon_tty_close(struct tty_struct *tty, struct file *filp) { } -static int nfcon_tty_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t nfcon_tty_write(struct tty_struct *tty, const u8 *buf, + size_t count) { nfputs(buf, count); return count; diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index e5393b4ba9f8..b98545f3edb5 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -184,7 +184,7 @@ void line_flush_chars(struct tty_struct *tty) line_flush_buffer(tty); } -int line_write(struct tty_struct *tty, const u8 *buf, int len) +ssize_t line_write(struct tty_struct *tty, const u8 *buf, size_t len) { struct line *line = tty->driver_data; unsigned long flags; diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index 8354024b6b35..e84fb9b4165e 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h @@ -64,7 +64,7 @@ extern void line_cleanup(struct tty_struct *tty); extern void line_hangup(struct tty_struct *tty); extern int line_setup(char **conf, unsigned nlines, char **def, char *init, char *name); -extern int line_write(struct tty_struct *tty, const u8 *buf, int len); +extern ssize_t line_write(struct tty_struct *tty, const u8 *buf, size_t len); extern unsigned int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); extern void line_flush_chars(struct tty_struct *tty); diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 182ec57e2d5c..7d1f8b398a46 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -52,7 +52,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) } -static int rs_write(struct tty_struct * tty, const u8 *buf, int count) +static ssize_t rs_write(struct tty_struct * tty, const u8 *buf, size_t count) { /* see drivers/char/serialX.c to reference original version */ diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 4f3dd93f1fd8..5af804c17a75 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -103,7 +103,7 @@ static void tpk_close(struct tty_struct *tty, struct file *filp) /* * TTY operations write function. */ -static int tpk_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t tpk_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct ttyprintk_port *tpkp = tty->driver_data; unsigned long flags; diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index c3cf086e7e36..da308be6c487 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -458,7 +458,8 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, return i; } -static int ipoctal_write_tty(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t ipoctal_write_tty(struct tty_struct *tty, const u8 *buf, + size_t count) { struct ipoctal_channel *channel = tty->driver_data; unsigned int char_copied; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 2f38e1cfe97a..2f3789515445 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1077,12 +1077,13 @@ static void capinc_tty_close(struct tty_struct *tty, struct file *filp) tty_port_close(&mp->port, tty, filp); } -static int capinc_tty_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t capinc_tty_write(struct tty_struct *tty, const u8 *buf, + size_t count) { struct capiminor *mp = tty->driver_data; struct sk_buff *skb; - pr_debug("capinc_tty_write(count=%d)\n", count); + pr_debug("capinc_tty_write(count=%zu)\n", count); spin_lock_bh(&mp->outlock); skb = mp->outskb; diff --git a/drivers/misc/bcm-vk/bcm_vk_tty.c b/drivers/misc/bcm-vk/bcm_vk_tty.c index 44851b607cce..2bce835ca43e 100644 --- a/drivers/misc/bcm-vk/bcm_vk_tty.c +++ b/drivers/misc/bcm-vk/bcm_vk_tty.c @@ -186,7 +186,8 @@ static void bcm_vk_tty_doorbell(struct bcm_vk *vk, u32 db_val) VK_BAR0_REGSEG_DB_BASE + VK_BAR0_REGSEG_TTY_DB_OFFSET); } -static int bcm_vk_tty_write(struct tty_struct *tty, const u8 *buffer, int count) +static ssize_t bcm_vk_tty_write(struct tty_struct *tty, const u8 *buffer, + size_t count) { int index; struct bcm_vk *vk; diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index 90d2fe00c0b9..ef38dcd3a887 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -760,7 +760,8 @@ static void sdio_uart_hangup(struct tty_struct *tty) tty_port_hangup(&port->port); } -static int sdio_uart_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t sdio_uart_write(struct tty_struct *tty, const u8 *buf, + size_t count) { struct sdio_uart_port *port = tty->driver_data; int ret; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 014a9d29bab5..3f424da87bf4 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1322,7 +1322,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) } /* close the requested serial port */ -static int hso_serial_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t hso_serial_write(struct tty_struct *tty, const u8 *buf, + size_t count) { struct hso_serial *serial = tty->driver_data; int space, tx_bytes; diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 8bbce6a4d7f5..99361618c31f 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -1021,7 +1021,8 @@ static unsigned int tty3215_write_room(struct tty_struct *tty) /* * String write routine for 3215 ttys */ -static int tty3215_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t tty3215_write(struct tty_struct *tty, const u8 *buf, + size_t count) { handle_write(tty->driver_data, buf, count); return count; diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 6374555a0937..363315fa1666 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -1803,7 +1803,8 @@ static void tty3270_do_write(struct tty3270 *tp, struct tty_struct *tty, /* * String write routine for 3270 ttys */ -static int tty3270_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t tty3270_write(struct tty_struct *tty, const u8 *buf, + size_t count) { struct tty3270 *tp; diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 831a8c7cacc2..892c18d2f87e 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -229,8 +229,8 @@ out: * tty device. The characters may come from user space or kernel space. This * routine will return the number of characters actually accepted for writing. */ -static int -sclp_tty_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t +sclp_tty_write(struct tty_struct *tty, const u8 *buf, size_t count) { if (sclp_tty_chars_count > 0) { sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0); diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index e148350c1e2c..218ae604f737 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -462,8 +462,8 @@ out: * user space or kernel space. This routine will return the * number of characters actually accepted for writing. */ -static int -sclp_vt220_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t +sclp_vt220_write(struct tty_struct *tty, const u8 *buf, size_t count) { return __sclp_vt220_write(buf, count, 1, 0, 1); } diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index ae9978b73d9b..b31f2afb0286 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -149,7 +149,7 @@ static void gdm_tty_send_complete(void *arg) tty_port_tty_wakeup(&gdm->port); } -static int gdm_tty_write(struct tty_struct *tty, const u8 *buf, int len) +static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len) { struct gdm *gdm = tty->driver_data; int remain = len; diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 97c7ddd0f53e..999ce613dca8 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -427,7 +427,7 @@ static void gb_tty_hangup(struct tty_struct *tty) tty_port_hangup(&gb_tty->port); } -static int gb_tty_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t gb_tty_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct gb_tty *gb_tty = tty->driver_data; diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 91cf294ec8c1..785558c65ae8 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -741,7 +741,7 @@ static void rs_flush_chars(struct tty_struct *tty) local_irq_restore(flags); } -static int rs_write(struct tty_struct * tty, const u8 *buf, int count) +static ssize_t rs_write(struct tty_struct * tty, const u8 *buf, size_t count) { int c, ret = 0; struct serial_state *info = tty->driver_data; diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index de36347e2145..a067628e01c8 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -466,7 +466,8 @@ static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data) * ehv_bc_tty_write_room() will never lie, so the tty layer will never send us * too much data. */ -static int ehv_bc_tty_write(struct tty_struct *ttys, const u8 *s, int count) +static ssize_t ehv_bc_tty_write(struct tty_struct *ttys, const u8 *s, + size_t count) { struct ehv_bc_data *bc = ttys->driver_data; unsigned long flags; diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index faa597ffbaf9..4591f940b7a1 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -185,7 +185,8 @@ static void goldfish_tty_hangup(struct tty_struct *tty) tty_port_hangup(tty->port); } -static int goldfish_tty_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t goldfish_tty_write(struct tty_struct *tty, const u8 *buf, + size_t count) { goldfish_tty_do_write(tty->index, buf, count); return count; diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 4c60d15c7a6f..e93e8072ec86 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -496,7 +496,7 @@ static int hvc_push(struct hvc_struct *hp) return n; } -static int hvc_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t hvc_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct hvc_struct *hp = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 2465d61b4e76..1de91fa23b04 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1257,7 +1257,7 @@ static void hvcs_hangup(struct tty_struct * tty) * tty_hangup will allow hvcs_write time to complete execution before it * terminates our device. */ -static int hvcs_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t hvcs_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct hvcs_struct *hvcsd = tty->driver_data; unsigned int unit_address; @@ -1299,7 +1299,8 @@ static int hvcs_write(struct tty_struct *tty, const u8 *buf, int count) unit_address = hvcsd->vdev->unit_address; while (count > 0) { - tosend = min(count, (HVCS_BUFF_LEN - hvcsd->chars_in_buffer)); + tosend = min_t(unsigned, count, + (HVCS_BUFF_LEN - hvcsd->chars_in_buffer)); /* * No more space, this probably means that the last call to * hvcs_write() didn't succeed and the buffer was filled up. diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 46dd62df2442..c57bd85aa488 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -904,7 +904,8 @@ static unsigned int hvsi_chars_in_buffer(struct tty_struct *tty) return hp->n_outbuf; } -static int hvsi_write(struct tty_struct *tty, const u8 *source, int count) +static ssize_t hvsi_write(struct tty_struct *tty, const u8 *source, + size_t count) { struct hvsi_struct *hp = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index cd43208c523c..b6de40815fb9 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -186,7 +186,8 @@ static void ipw_write_packet_sent_callback(void *callback_data, tty->tx_bytes_queued -= packet_length; } -static int ipw_write(struct tty_struct *linux_tty, const u8 *buf, int count) +static ssize_t ipw_write(struct tty_struct *linux_tty, const u8 *buf, + size_t count) { struct ipw_tty *tty = linux_tty->driver_data; int room, ret; diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index cf4ef0c38624..369ec71c24ef 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -796,8 +796,8 @@ static void mips_ejtag_fdc_tty_hangup(struct tty_struct *tty) tty_port_hangup(tty->port); } -static int mips_ejtag_fdc_tty_write(struct tty_struct *tty, const u8 *buf, - int total) +static ssize_t mips_ejtag_fdc_tty_write(struct tty_struct *tty, const u8 *buf, + size_t total) { int count, block; struct mips_ejtag_fdc_tty_port *dport = tty->driver_data; @@ -816,7 +816,7 @@ static int mips_ejtag_fdc_tty_write(struct tty_struct *tty, const u8 *buf, */ spin_lock(&dport->xmit_lock); /* Work out how many bytes we can write to the xmit buffer */ - total = min(total, (int)(priv->xmit_size - dport->xmit_cnt)); + total = min_t(size_t, total, priv->xmit_size - dport->xmit_cnt); atomic_add(total, &priv->xmit_total); dport->xmit_cnt += total; /* Write the actual bytes (may need splitting if it wraps) */ diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index d94cf1be651b..bf3f87ba3a92 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -487,7 +487,7 @@ module_param(ttymajor, int, 0); */ static int moxa_open(struct tty_struct *, struct file *); static void moxa_close(struct tty_struct *, struct file *); -static int moxa_write(struct tty_struct *, const u8 *, int); +static ssize_t moxa_write(struct tty_struct *, const u8 *, size_t); static unsigned int moxa_write_room(struct tty_struct *); static void moxa_flush_buffer(struct tty_struct *); static unsigned int moxa_chars_in_buffer(struct tty_struct *); @@ -1499,7 +1499,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) tty_port_close(&ch->port, tty, filp); } -static int moxa_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t moxa_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct moxa_port *ch = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index a5dfd08d4ea2..10aa4ed38793 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -901,7 +901,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) tty_port_close(tty->port, tty, filp); } -static int mxser_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t mxser_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct mxser_port *info = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index d167e36873fe..3e5cc30941a7 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -4256,7 +4256,7 @@ static void gsmtty_hangup(struct tty_struct *tty) gsm_dlci_begin_close(dlci); } -static int gsmtty_write(struct tty_struct *tty, const u8 *buf, int len) +static ssize_t gsmtty_write(struct tty_struct *tty, const u8 *buf, size_t len) { int sent; struct gsm_dlci *dlci = tty->driver_data; diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index b3756402f5d9..02cd40147b3a 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1599,7 +1599,8 @@ static void ntty_hangup(struct tty_struct *tty) * called when the userspace process writes to the tty (/dev/noz*). * Data is inserted into a fifo, which is then read and transferred to the modem. */ -static int ntty_write(struct tty_struct *tty, const u8 *buffer, int count) +static ssize_t ntty_write(struct tty_struct *tty, const u8 *buffer, + size_t count) { int rval = -EINVAL; struct nozomi *dc = get_dc_by_tty(tty); diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 335f5744f320..df08f13052ff 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -108,7 +108,7 @@ static void pty_unthrottle(struct tty_struct *tty) * the other side of the pty/tty pair. */ -static int pty_write(struct tty_struct *tty, const u8 *buf, int c) +static ssize_t pty_write(struct tty_struct *tty, const u8 *buf, size_t c) { struct tty_struct *to = tty->link; diff --git a/drivers/tty/rpmsg_tty.c b/drivers/tty/rpmsg_tty.c index 29db413bbc03..60a2915f5cfe 100644 --- a/drivers/tty/rpmsg_tty.c +++ b/drivers/tty/rpmsg_tty.c @@ -73,7 +73,8 @@ static void rpmsg_tty_close(struct tty_struct *tty, struct file *filp) return tty_port_close(tty->port, tty, filp); } -static int rpmsg_tty_write(struct tty_struct *tty, const u8 *buf, int len) +static ssize_t rpmsg_tty_write(struct tty_struct *tty, const u8 *buf, + size_t len) { struct rpmsg_tty_port *cport = tty->driver_data; struct rpmsg_device *rpdev; @@ -86,7 +87,7 @@ static int rpmsg_tty_write(struct tty_struct *tty, const u8 *buf, int len) if (msg_max_size < 0) return msg_max_size; - msg_size = min(len, msg_max_size); + msg_size = min_t(unsigned int, len, msg_max_size); /* * Use rpmsg_trysend instead of rpmsg_send to send the message so the caller is not diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 2a04d19d5ec0..e93850f6447a 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c @@ -304,7 +304,8 @@ static unsigned int kgdb_nmi_tty_write_room(struct tty_struct *tty) return 2048; } -static int kgdb_nmi_tty_write(struct tty_struct *tty, const u8 *buf, int c) +static ssize_t kgdb_nmi_tty_write(struct tty_struct *tty, const u8 *buf, + size_t c) { int i; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index d5b682ff20b3..7bdc21d5e13b 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -580,7 +580,7 @@ static void uart_flush_chars(struct tty_struct *tty) uart_start(tty); } -static int uart_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t uart_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct uart_state *state = tty->driver_data; struct uart_port *port; diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 0264e9f7699c..8112d9d5a0d8 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -745,7 +745,7 @@ static void update_tx_timer(struct slgt_info *info) } } -static int write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t write(struct tty_struct *tty, const u8 *buf, size_t count) { int ret = 0; struct slgt_info *info = tty->driver_data; @@ -754,7 +754,7 @@ static int write(struct tty_struct *tty, const u8 *buf, int count) if (sanity_check(info, tty->name, "write")) return -EIO; - DBGINFO(("%s write count=%d\n", info->device_name, count)); + DBGINFO(("%s write count=%zu\n", info->device_name, count)); if (!info->tx_buf || (count > info->max_frame_size)) return -EIO; diff --git a/drivers/tty/ttynull.c b/drivers/tty/ttynull.c index 6b74ebaa0f2d..e4c4273993bc 100644 --- a/drivers/tty/ttynull.c +++ b/drivers/tty/ttynull.c @@ -29,7 +29,8 @@ static void ttynull_hangup(struct tty_struct *tty) tty_port_hangup(&ttynull_port); } -static int ttynull_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t ttynull_write(struct tty_struct *tty, const u8 *buf, + size_t count) { return count; } diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index c223879039b8..9cc569174c83 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -804,7 +804,7 @@ static void vcc_hangup(struct tty_struct *tty) tty_port_hangup(tty->port); } -static int vcc_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t vcc_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct vcc_port *port; struct vio_vcc *pkt; @@ -826,7 +826,8 @@ static int vcc_write(struct tty_struct *tty, const u8 *buf, int count) while (count > 0) { /* Minimum of data to write and space available */ - tosend = min(count, (VCC_BUFF_LEN - port->chars_in_buffer)); + tosend = min_t(size_t, count, + (VCC_BUFF_LEN - port->chars_in_buffer)); if (!tosend) break; diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index ea7c20d66acb..5c47f77804f0 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3238,7 +3238,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) * /dev/ttyN handling */ -static int con_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t con_write(struct tty_struct *tty, const u8 *buf, size_t count) { int retval; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 913b07b30d33..3591880d96bd 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -789,7 +789,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) tty_port_close(&acm->port, tty, filp); } -static int acm_tty_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t acm_tty_write(struct tty_struct *tty, const u8 *buf, + size_t count) { struct acm *acm = tty->driver_data; int stat; @@ -800,7 +801,7 @@ static int acm_tty_write(struct tty_struct *tty, const u8 *buf, int count) if (!count) return 0; - dev_vdbg(&acm->data->dev, "%d bytes from tty layer\n", count); + dev_vdbg(&acm->data->dev, "%zu bytes from tty layer\n", count); spin_lock_irqsave(&acm->write_lock, flags); wbn = acm_wb_alloc(acm); @@ -817,7 +818,7 @@ static int acm_tty_write(struct tty_struct *tty, const u8 *buf, int count) } count = (count > acm->writesize) ? acm->writesize : count; - dev_vdbg(&acm->data->dev, "writing %d bytes\n", count); + dev_vdbg(&acm->data->dev, "writing %zu bytes\n", count); memcpy(wb->buf, buf, count); wb->len = count; diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 3e6b750aa4fc..a92eb6d90976 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -734,12 +734,12 @@ exit: spin_unlock_irq(&port->port_lock); } -static int gs_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t gs_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct gs_port *port = tty->driver_data; unsigned long flags; - pr_vdebug("gs_write: ttyGS%d (%p) writing %d bytes\n", + pr_vdebug("gs_write: ttyGS%d (%p) writing %zu bytes\n", port->port_num, tty, count); spin_lock_irqsave(&port->port_lock, flags); diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index 5b82bdd82ba9..b74e98e94393 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -208,7 +208,8 @@ static void dbc_tty_close(struct tty_struct *tty, struct file *file) tty_port_close(&port->port, tty, file); } -static int dbc_tty_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t dbc_tty_write(struct tty_struct *tty, const u8 *buf, + size_t count) { struct dbc_port *port = tty->driver_data; unsigned long flags; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 51f738ea3f77..17b09f03ef84 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -361,7 +361,7 @@ static void serial_cleanup(struct tty_struct *tty) module_put(owner); } -static int serial_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t serial_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct usb_serial_port *port = tty->driver_data; int retval = -ENODEV; @@ -369,7 +369,7 @@ static int serial_write(struct tty_struct *tty, const u8 *buf, int count) if (port->serial->dev->state == USB_STATE_NOTATTACHED) goto exit; - dev_dbg(&port->dev, "%s - %d byte(s)\n", __func__, count); + dev_dbg(&port->dev, "%s - %zu byte(s)\n", __func__, count); retval = port->serial->type->write(tty, port, buf, count); if (retval < 0) diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index c5299d952e59..18beff0cec1a 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -72,8 +72,8 @@ struct serial_struct; * is closed for the last time freeing up the resources. This is * actually the second part of shutdown for routines that might sleep. * - * @write: ``int ()(struct tty_struct *tty, const unsigned char *buf, - * int count)`` + * @write: ``ssize_t ()(struct tty_struct *tty, const unsigned char *buf, + * size_t count)`` * * This routine is called by the kernel to write a series (@count) of * characters (@buf) to the @tty device. The characters may come from @@ -356,7 +356,7 @@ struct tty_operations { void (*close)(struct tty_struct * tty, struct file * filp); void (*shutdown)(struct tty_struct *tty); void (*cleanup)(struct tty_struct *tty); - int (*write)(struct tty_struct *tty, const u8 *buf, int count); + ssize_t (*write)(struct tty_struct *tty, const u8 *buf, size_t count); int (*put_char)(struct tty_struct *tty, u8 ch); void (*flush_chars)(struct tty_struct *tty); unsigned int (*write_room)(struct tty_struct *tty); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 3b5f8404dc84..33b135ed59c4 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -779,14 +779,15 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) tty_port_close(&dev->port, tty, filp); } -static int rfcomm_tty_write(struct tty_struct *tty, const u8 *buf, int count) +static ssize_t rfcomm_tty_write(struct tty_struct *tty, const u8 *buf, + size_t count) { struct rfcomm_dev *dev = tty->driver_data; struct rfcomm_dlc *dlc = dev->dlc; struct sk_buff *skb; int sent = 0, size; - BT_DBG("tty %p count %d", tty, count); + BT_DBG("tty %p count %zu", tty, count); while (count) { size = min_t(uint, count, dlc->mtu); -- cgit v1.2.3 From 3e04ba41f22490873a60816ea31c6848d3426255 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:04 +0200 Subject: tty: audit: unify to u8 Somewhere, we use 'char', somewhere 'unsigned char'. Unify to 'u8' as the rest of the tty layer does. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230810091510.13006-31-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty.h | 4 ++-- drivers/tty/tty_audit.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index e31cd9f281de..50862f98273e 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -101,13 +101,13 @@ extern int tty_ldisc_autoload; #ifdef CONFIG_AUDIT void tty_audit_add_data(const struct tty_struct *tty, const void *data, size_t size); -void tty_audit_tiocsti(const struct tty_struct *tty, char ch); +void tty_audit_tiocsti(const struct tty_struct *tty, u8 ch); #else static inline void tty_audit_add_data(const struct tty_struct *tty, const void *data, size_t size) { } -static inline void tty_audit_tiocsti(const struct tty_struct *tty, char ch) +static inline void tty_audit_tiocsti(const struct tty_struct *tty, u8 ch) { } #endif diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index 24d010589379..1d81eeefb068 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c @@ -17,7 +17,7 @@ struct tty_audit_buf { dev_t dev; /* The TTY which the data is from */ bool icanon; size_t valid; - unsigned char *data; /* Allocated size N_TTY_BUF_SIZE */ + u8 *data; /* Allocated size N_TTY_BUF_SIZE */ }; static struct tty_audit_buf *tty_audit_buf_ref(void) @@ -59,7 +59,7 @@ static void tty_audit_buf_free(struct tty_audit_buf *buf) } static void tty_audit_log(const char *description, dev_t dev, - const unsigned char *data, size_t size) + const u8 *data, size_t size) { struct audit_buffer *ab; pid_t pid = task_pid_nr(current); @@ -134,7 +134,7 @@ void tty_audit_fork(struct signal_struct *sig) /* * tty_audit_tiocsti - Log TIOCSTI */ -void tty_audit_tiocsti(const struct tty_struct *tty, char ch) +void tty_audit_tiocsti(const struct tty_struct *tty, u8 ch) { dev_t dev; -- cgit v1.2.3 From 49b8220cee4aa3d7aaaf42fd7f316b7f8fb710da Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:05 +0200 Subject: tty: ldops: unify to u8 Some hooks in struct tty_ldisc_ops still reference buffers by 'unsigned char'. Unify to 'u8' as the rest of the tty layer does. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Cc: Dmitry Torokhov Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230810091510.13006-32-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_ldisc.c | 6 +++--- drivers/input/serio/serport.c | 4 ++-- drivers/net/ppp/ppp_async.c | 9 ++++----- drivers/net/ppp/ppp_synctty.c | 7 +++---- drivers/tty/n_gsm.c | 7 +++---- drivers/tty/n_hdlc.c | 6 +++--- drivers/tty/n_null.c | 7 +++---- drivers/tty/n_tty.c | 11 +++++------ include/linux/tty_ldisc.h | 13 ++++++------- net/nfc/nci/uart.c | 6 +++--- 10 files changed, 35 insertions(+), 41 deletions(-) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index b41071282ce5..997f7e98eb62 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -806,14 +806,14 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, unsigned int cmd, * We don't provide read/write/poll interface for user space. */ static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t nr, - void **cookie, unsigned long offset) + u8 *buf, size_t nr, void **cookie, + unsigned long offset) { return 0; } static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, - const unsigned char *data, size_t count) + const u8 *data, size_t count) { return 0; } diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 5ce8d9f10f3e..1db3f30011c4 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -158,8 +158,8 @@ out: */ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, - unsigned char *kbuf, size_t nr, - void **cookie, unsigned long offset) + u8 *kbuf, size_t nr, void **cookie, + unsigned long offset) { struct serport *serport = tty->disc_data; struct serio *serio; diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index cfd5cb609d99..fbaaa8c102a1 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -257,9 +257,8 @@ static void ppp_asynctty_hangup(struct tty_struct *tty) * Pppd reads and writes packets via /dev/ppp instead. */ static ssize_t -ppp_asynctty_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t count, - void **cookie, unsigned long offset) +ppp_asynctty_read(struct tty_struct *tty, struct file *file, u8 *buf, + size_t count, void **cookie, unsigned long offset) { return -EAGAIN; } @@ -269,8 +268,8 @@ ppp_asynctty_read(struct tty_struct *tty, struct file *file, * from the ppp generic stuff. */ static ssize_t -ppp_asynctty_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t count) +ppp_asynctty_write(struct tty_struct *tty, struct file *file, const u8 *buf, + size_t count) { return -EAGAIN; } diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 164c9053f73b..ebcdffdf4f0e 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -255,8 +255,7 @@ static void ppp_sync_hangup(struct tty_struct *tty) * Pppd reads and writes packets via /dev/ppp instead. */ static ssize_t -ppp_sync_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t count, +ppp_sync_read(struct tty_struct *tty, struct file *file, u8 *buf, size_t count, void **cookie, unsigned long offset) { return -EAGAIN; @@ -267,8 +266,8 @@ ppp_sync_read(struct tty_struct *tty, struct file *file, * from the ppp generic stuff. */ static ssize_t -ppp_sync_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t count) +ppp_sync_write(struct tty_struct *tty, struct file *file, const u8 *buf, + size_t count) { return -EAGAIN; } diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 3e5cc30941a7..42759500b79e 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3638,9 +3638,8 @@ static void gsmld_write_wakeup(struct tty_struct *tty) * This code must be sure never to sleep through a hangup. */ -static ssize_t gsmld_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t nr, - void **cookie, unsigned long offset) +static ssize_t gsmld_read(struct tty_struct *tty, struct file *file, u8 *buf, + size_t nr, void **cookie, unsigned long offset) { return -EOPNOTSUPP; } @@ -3660,7 +3659,7 @@ static ssize_t gsmld_read(struct tty_struct *tty, struct file *file, */ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t nr) + const u8 *buf, size_t nr) { struct gsm_mux *gsm = tty->disc_data; unsigned long flags; diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 9be0932d07e0..a670419efe79 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -425,8 +425,8 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const u8 *data, * Returns the number of bytes returned or error code. */ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, - __u8 *kbuf, size_t nr, - void **cookie, unsigned long offset) + u8 *kbuf, size_t nr, void **cookie, + unsigned long offset) { struct n_hdlc *n_hdlc = tty->disc_data; int ret = 0; @@ -518,7 +518,7 @@ done_with_rbuf: * Returns the number of bytes written (or error code). */ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, - const unsigned char *data, size_t count) + const u8 *data, size_t count) { struct n_hdlc *n_hdlc = tty->disc_data; int error = 0; diff --git a/drivers/tty/n_null.c b/drivers/tty/n_null.c index 4a0d8bb2fb4c..5a429d923eb3 100644 --- a/drivers/tty/n_null.c +++ b/drivers/tty/n_null.c @@ -10,15 +10,14 @@ * Copyright (C) Intel 2017 */ -static ssize_t n_null_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t nr, - void **cookie, unsigned long offset) +static ssize_t n_null_read(struct tty_struct *tty, struct file *file, u8 *buf, + size_t nr, void **cookie, unsigned long offset) { return -EOPNOTSUPP; } static ssize_t n_null_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t nr) + const u8 *buf, size_t nr) { return -EOPNOTSUPP; } diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 1053b2adb04c..f44f38bb412e 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2128,12 +2128,11 @@ static int job_control(struct tty_struct *tty, struct file *file) * claims non-exclusive termios_rwsem; * publishes read_tail */ -static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, - unsigned char *kbuf, size_t nr, - void **cookie, unsigned long offset) +static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf, + size_t nr, void **cookie, unsigned long offset) { struct n_tty_data *ldata = tty->disc_data; - unsigned char *kb = kbuf; + u8 *kb = kbuf; DEFINE_WAIT_FUNC(wait, woken_wake_function); int c; int minimum, time; @@ -2332,9 +2331,9 @@ more_to_be_read: */ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t nr) + const u8 *buf, size_t nr) { - const unsigned char *b = buf; + const u8 *b = buf; DEFINE_WAIT_FUNC(wait, woken_wake_function); int c; ssize_t retval = 0; diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index a661d7df5497..af01e89074b2 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -90,8 +90,8 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * * Optional. * - * @read: [TTY] ``ssize_t ()(struct tty_struct *tty, struct file *file, - * unsigned char *buf, size_t nr)`` + * @read: [TTY] ``ssize_t ()(struct tty_struct *tty, struct file *file, u8 *buf, + * size_t nr)`` * * This function is called when the user requests to read from the @tty. * The line discipline will return whatever characters it has buffered up @@ -102,7 +102,7 @@ int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, * Optional: %EIO unless provided. Can sleep. * * @write: [TTY] ``ssize_t ()(struct tty_struct *tty, struct file *file, - * const unsigned char *buf, size_t nr)`` + * const u8 *buf, size_t nr)`` * * This function is called when the user requests to write to the @tty. * The line discipline will deliver the characters to the low-level tty @@ -238,11 +238,10 @@ struct tty_ldisc_ops { int (*open)(struct tty_struct *tty); void (*close)(struct tty_struct *tty); void (*flush_buffer)(struct tty_struct *tty); - ssize_t (*read)(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t nr, - void **cookie, unsigned long offset); + ssize_t (*read)(struct tty_struct *tty, struct file *file, u8 *buf, + size_t nr, void **cookie, unsigned long offset); ssize_t (*write)(struct tty_struct *tty, struct file *file, - const unsigned char *buf, size_t nr); + const u8 *buf, size_t nr); int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); int (*compat_ioctl)(struct tty_struct *tty, unsigned int cmd, diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index 93775c540287..ed1508a9e093 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -345,14 +345,14 @@ static int nci_uart_tty_ioctl(struct tty_struct *tty, unsigned int cmd, /* We don't provide read/write/poll interface for user space. */ static ssize_t nci_uart_tty_read(struct tty_struct *tty, struct file *file, - unsigned char *buf, size_t nr, - void **cookie, unsigned long offset) + u8 *buf, size_t nr, void **cookie, + unsigned long offset) { return 0; } static ssize_t nci_uart_tty_write(struct tty_struct *tty, struct file *file, - const unsigned char *data, size_t count) + const u8 *data, size_t count) { return 0; } -- cgit v1.2.3 From 8428e5223ea2e195f5790bff770b804f3918f3f4 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:06 +0200 Subject: tty: hvc: convert counts to size_t Unify the type of tty_operations::write() counters with the 'count' parameter. I.e. use size_t for them. Signed-off-by: "Jiri Slaby (SUSE)" Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230810091510.13006-33-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_console.c | 2 +- drivers/tty/hvc/hvcs.c | 6 +++--- drivers/tty/hvc/hvsi.c | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index e93e8072ec86..959fae54ca39 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -500,7 +500,7 @@ static ssize_t hvc_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct hvc_struct *hp = tty->driver_data; unsigned long flags; - int rsize, written = 0; + size_t rsize, written = 0; /* This write was probably executed during a tty close. */ if (!hp) diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 1de91fa23b04..d29fdfe9d93d 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1263,8 +1263,8 @@ static ssize_t hvcs_write(struct tty_struct *tty, const u8 *buf, size_t count) unsigned int unit_address; const unsigned char *charbuf; unsigned long flags; - int total_sent = 0; - int tosend = 0; + size_t total_sent = 0; + size_t tosend = 0; int result = 0; /* @@ -1299,7 +1299,7 @@ static ssize_t hvcs_write(struct tty_struct *tty, const u8 *buf, size_t count) unit_address = hvcsd->vdev->unit_address; while (count > 0) { - tosend = min_t(unsigned, count, + tosend = min_t(size_t, count, (HVCS_BUFF_LEN - hvcsd->chars_in_buffer)); /* * No more space, this probably means that the last call to diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index c57bd85aa488..a94068bce76f 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -909,8 +909,8 @@ static ssize_t hvsi_write(struct tty_struct *tty, const u8 *source, { struct hvsi_struct *hp = tty->driver_data; unsigned long flags; - int total = 0; - int origcount = count; + size_t total = 0; + size_t origcount = count; spin_lock_irqsave(&hp->lock, flags); @@ -928,7 +928,7 @@ static ssize_t hvsi_write(struct tty_struct *tty, const u8 *source, * will see there is no room in outbuf and return. */ while ((count > 0) && (hvsi_write_room(tty) > 0)) { - int chunksize = min_t(int, count, hvsi_write_room(tty)); + size_t chunksize = min_t(size_t, count, hvsi_write_room(tty)); BUG_ON(hp->n_outbuf < 0); memcpy(hp->outbuf + hp->n_outbuf, source, chunksize); @@ -952,8 +952,8 @@ out: spin_unlock_irqrestore(&hp->lock, flags); if (total != origcount) - pr_debug("%s: wanted %i, only wrote %i\n", __func__, origcount, - total); + pr_debug("%s: wanted %zu, only wrote %zu\n", __func__, + origcount, total); return total; } -- cgit v1.2.3 From cfc7c12b508ac0a4ebf20a187e471e5b1dc6402c Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:07 +0200 Subject: tty: vcc: convert counts to size_t Unify the type of tty_operations::write() counters with the 'count' parameter. I.e. use size_t for them. This includes changing vcc_port::chars_in_buffer to size_t to keep min() and avoid min_t(). Signed-off-by: "Jiri Slaby (SUSE)" Cc: "David S. Miller" Link: https://lore.kernel.org/r/20230810091510.13006-34-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/sparc/include/asm/vio.h | 2 +- drivers/tty/vcc.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h index 8a0c3c11c9ce..587fb7841096 100644 --- a/arch/sparc/include/asm/vio.h +++ b/arch/sparc/include/asm/vio.h @@ -284,7 +284,7 @@ struct vio_dring_state { struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES]; }; -#define VIO_TAG_SIZE ((int)sizeof(struct vio_msg_tag)) +#define VIO_TAG_SIZE (sizeof(struct vio_msg_tag)) #define VIO_VCC_MTU_SIZE (LDC_PACKET_SIZE - VIO_TAG_SIZE) struct vio_vcc { diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index 9cc569174c83..a39ed981bfd3 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -36,7 +36,7 @@ struct vcc_port { * and guarantee that any characters that the driver accepts will * be eventually sent, either immediately or later. */ - int chars_in_buffer; + size_t chars_in_buffer; struct vio_vcc buffer; struct timer_list rx_timer; @@ -385,7 +385,7 @@ static void vcc_tx_timer(struct timer_list *t) struct vcc_port *port = from_timer(port, t, tx_timer); struct vio_vcc *pkt; unsigned long flags; - int tosend = 0; + size_t tosend = 0; int rv; spin_lock_irqsave(&port->lock, flags); @@ -809,8 +809,8 @@ static ssize_t vcc_write(struct tty_struct *tty, const u8 *buf, size_t count) struct vcc_port *port; struct vio_vcc *pkt; unsigned long flags; - int total_sent = 0; - int tosend = 0; + size_t total_sent = 0; + size_t tosend = 0; int rv = -EINVAL; port = vcc_get_ne(tty->index); @@ -847,7 +847,7 @@ static ssize_t vcc_write(struct tty_struct *tty, const u8 *buf, size_t count) * hypervisor actually took it because we have it buffered. */ rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend)); - vccdbg("VCC: write: ldc_write(%d)=%d\n", + vccdbg("VCC: write: ldc_write(%zu)=%d\n", (VIO_TAG_SIZE + tosend), rv); total_sent += tosend; @@ -864,7 +864,7 @@ static ssize_t vcc_write(struct tty_struct *tty, const u8 *buf, size_t count) vcc_put(port, false); - vccdbg("VCC: write: total=%d rv=%d", total_sent, rv); + vccdbg("VCC: write: total=%zu rv=%d", total_sent, rv); return total_sent ? total_sent : rv; } -- cgit v1.2.3 From c3e5c706aefc3ceee941c1e7bd72084d3aeca37b Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:08 +0200 Subject: tty: gdm724x: convert counts to size_t Unify the type of tty_operations::write() counters with the 'count' parameter. I.e. use size_t for them. This includes changing constants to UL to keep min() and avoid min_t(). Signed-off-by: "Jiri Slaby (SUSE)" Cc: linux-staging@lists.linux.dev Link: https://lore.kernel.org/r/20230810091510.13006-35-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_tty.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index b31f2afb0286..cbaaa8fa7474 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -17,9 +17,9 @@ #define GDM_TTY_MAJOR 0 #define GDM_TTY_MINOR 32 -#define WRITE_SIZE 2048 +#define WRITE_SIZE 2048UL -#define MUX_TX_MAX_SIZE 2048 +#define MUX_TX_MAX_SIZE 2048UL static inline bool gdm_tty_ready(struct gdm *gdm) { @@ -152,9 +152,8 @@ static void gdm_tty_send_complete(void *arg) static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len) { struct gdm *gdm = tty->driver_data; - int remain = len; - int sent_len = 0; - int sending_len = 0; + size_t remain = len; + size_t sent_len = 0; if (!gdm_tty_ready(gdm)) return -ENODEV; @@ -163,7 +162,7 @@ static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len) return 0; while (1) { - sending_len = min(MUX_TX_MAX_SIZE, remain); + size_t sending_len = min(MUX_TX_MAX_SIZE, remain); gdm->tty_dev->send_func(gdm->tty_dev->priv_dev, (void *)(buf + sent_len), sending_len, -- cgit v1.2.3 From 6fcd3b67284b83af144dafe45c2766933101cc2b Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:09 +0200 Subject: tty: hso: simplify hso_serial_write() There is no need for two more variables in hso_serial_write(). Switch to min_t() and eliminate those. Furthermore, the 'if-goto' is superfluous as memcpy() of zero count is a nop. So is addition of zero. So remove the 'if-goto' completely. Signed-off-by: "Jiri Slaby (SUSE)" Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Link: https://lore.kernel.org/r/20230810091510.13006-36-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/hso.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 3f424da87bf4..83b8452220ec 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1326,7 +1326,6 @@ static ssize_t hso_serial_write(struct tty_struct *tty, const u8 *buf, size_t count) { struct hso_serial *serial = tty->driver_data; - int space, tx_bytes; unsigned long flags; /* sanity check */ @@ -1337,21 +1336,16 @@ static ssize_t hso_serial_write(struct tty_struct *tty, const u8 *buf, spin_lock_irqsave(&serial->serial_lock, flags); - space = serial->tx_data_length - serial->tx_buffer_count; - tx_bytes = (count < space) ? count : space; + count = min_t(size_t, serial->tx_data_length - serial->tx_buffer_count, + count); + memcpy(serial->tx_buffer + serial->tx_buffer_count, buf, count); + serial->tx_buffer_count += count; - if (!tx_bytes) - goto out; - - memcpy(serial->tx_buffer + serial->tx_buffer_count, buf, tx_bytes); - serial->tx_buffer_count += tx_bytes; - -out: spin_unlock_irqrestore(&serial->serial_lock, flags); hso_kick_transmit(serial); /* done */ - return tx_bytes; + return count; } /* how much room is there for writing */ -- cgit v1.2.3 From c70fd7c0e905b0a13b2d941f558d47105cb75821 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 11:15:10 +0200 Subject: tty: rfcomm: convert counts to size_t Unify the type of tty_operations::write() counters with the 'count' parameter. I.e. use size_t for them. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Link: https://lore.kernel.org/r/20230810091510.13006-37-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/rfcomm/tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 33b135ed59c4..94ec913dfb76 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -785,12 +785,12 @@ static ssize_t rfcomm_tty_write(struct tty_struct *tty, const u8 *buf, struct rfcomm_dev *dev = tty->driver_data; struct rfcomm_dlc *dlc = dev->dlc; struct sk_buff *skb; - int sent = 0, size; + size_t sent = 0, size; BT_DBG("tty %p count %zu", tty, count); while (count) { - size = min_t(uint, count, dlc->mtu); + size = min_t(size_t, count, dlc->mtu); skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC); if (!skb) -- cgit v1.2.3 From e67d7f60d2382677c25de10b2e4d8d3717ace91f Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Thu, 10 Aug 2023 12:39:00 +0200 Subject: tty: gdm724x: simplify gdm_tty_write() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit len and remain can never be negative in gdm_tty_write(). So remove such a check and move the check of remaining bytes to the loop condition. This way, the preceding 'if' is now superfluous too. Fix all that and make the code cleaner. Signed-off-by: Jiri Slaby (SUSE) Reported-by: Dan Carpenter Reviewed-by: Ilpo Järvinen Cc: linux-staging@lists.linux.dev Link: https://lore.kernel.org/r/20230810103900.19353-1-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_tty.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index cbaaa8fa7474..67d9bf41e836 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -158,10 +158,7 @@ static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len) if (!gdm_tty_ready(gdm)) return -ENODEV; - if (!len) - return 0; - - while (1) { + while (remain) { size_t sending_len = min(MUX_TX_MAX_SIZE, remain); gdm->tty_dev->send_func(gdm->tty_dev->priv_dev, (void *)(buf + sent_len), @@ -171,8 +168,6 @@ static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len) gdm); sent_len += sending_len; remain -= sending_len; - if (remain <= 0) - break; } return len; -- cgit v1.2.3 From 2f4926723ac7343ae11861d0ba2aaa8e04bd3ca1 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 10:53:22 +0200 Subject: tty: gdm724x: use min_t() for size_t varable and a constant My thinking was that ulong is the same as size_t everywhere. No, size_t is uint on 32bit. So the below commit introduced a build warning on 32bit: .../gdm724x/gdm_tty.c:165:24: warning: comparison of distinct pointer types ('typeof (2048UL) *' (aka 'unsigned long *') and 'typeof (remain) *' (aka 'unsigned int *')) To fix this, partially revert the commit (remove constants' suffixes) and switch to min_t() in this case instead. /me would hope for Z (or alike) suffix for constants. Signed-off-by: "Jiri Slaby (SUSE)" Fixes: c3e5c706aefc (tty: gdm724x: convert counts to size_t) Reported-by: Nathan Chancellor Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202308151953.rNNnAR2N-lkp@intel.com/ Reviewed-by: Geert Uytterhoeven Tested-by: Nathan Chancellor # build Link: https://lore.kernel.org/r/20230816085322.22065-1-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_tty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index 67d9bf41e836..32b2e817ff04 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -17,9 +17,9 @@ #define GDM_TTY_MAJOR 0 #define GDM_TTY_MINOR 32 -#define WRITE_SIZE 2048UL +#define WRITE_SIZE 2048 -#define MUX_TX_MAX_SIZE 2048UL +#define MUX_TX_MAX_SIZE 2048 static inline bool gdm_tty_ready(struct gdm *gdm) { @@ -159,7 +159,7 @@ static ssize_t gdm_tty_write(struct tty_struct *tty, const u8 *buf, size_t len) return -ENODEV; while (remain) { - size_t sending_len = min(MUX_TX_MAX_SIZE, remain); + size_t sending_len = min_t(size_t, MUX_TX_MAX_SIZE, remain); gdm->tty_dev->send_func(gdm->tty_dev->priv_dev, (void *)(buf + sent_len), sending_len, -- cgit v1.2.3 From d4d13ff3ac78b41bfaefd5ad1efd72cfbf43f288 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:21 +0200 Subject: tty: tty_buffer: switch data type to u8 There is no reason to have tty_buffer::data typed as unsigned long. Switch to u8, but preserve the ulong alignment using __aligned. This allows for the cast removal from char_buf_ptr(). And for use of struct_size() in the allocation in tty_buffer_alloc() -- in the next patch. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- include/linux/tty_buffer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/tty_buffer.h b/include/linux/tty_buffer.h index e45cba81d0e9..31125e3be3c5 100644 --- a/include/linux/tty_buffer.h +++ b/include/linux/tty_buffer.h @@ -19,12 +19,12 @@ struct tty_buffer { unsigned int read; bool flags; /* Data points here */ - unsigned long data[]; + u8 data[] __aligned(sizeof(unsigned long)); }; static inline u8 *char_buf_ptr(struct tty_buffer *b, unsigned int ofs) { - return ((u8 *)b->data) + ofs; + return b->data + ofs; } static inline u8 *flag_buf_ptr(struct tty_buffer *b, unsigned int ofs) -- cgit v1.2.3 From 46bc78c81b65044fa7bd4781e6501b756b3a86bc Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:22 +0200 Subject: tty: tty_buffer: use struct_size() in tty_buffer_alloc() Now, that tty_buffer::data has the right type, use struct_size() for size calculation. struct_size() makes the code less error-prone and more readable. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 684d099cbe11..c94df1a2d7f8 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -177,8 +177,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) */ if (atomic_read(&port->buf.mem_used) > port->buf.mem_limit) return NULL; - p = kmalloc(sizeof(struct tty_buffer) + 2 * size, - GFP_ATOMIC | __GFP_NOWARN); + p = kmalloc(struct_size(p, data, 2 * size), GFP_ATOMIC | __GFP_NOWARN); if (p == NULL) return NULL; -- cgit v1.2.3 From c26405fd289b74225b111b8f23e9e7eae1a02513 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:23 +0200 Subject: tty: tty_buffer: unify tty_insert_flip_string_{fixed_flag,flags}() They both do the same except for flags. One mem-copies the flags from the caller, the other mem-sets to one flag given by the caller. This can be unified with a simple if in the unified function. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/tty/tty_buffer.rst | 6 ++- drivers/tty/tty_buffer.c | 70 +++++++---------------------- include/linux/tty_flip.h | 46 +++++++++++++++++-- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Documentation/driver-api/tty/tty_buffer.rst b/Documentation/driver-api/tty/tty_buffer.rst index a39d4781e0d2..774dc119c312 100644 --- a/Documentation/driver-api/tty/tty_buffer.rst +++ b/Documentation/driver-api/tty/tty_buffer.rst @@ -15,10 +15,12 @@ Flip Buffer Management ====================== .. kernel-doc:: drivers/tty/tty_buffer.c - :identifiers: tty_prepare_flip_string tty_insert_flip_string_fixed_flag - tty_insert_flip_string_flags __tty_insert_flip_char + :identifiers: tty_prepare_flip_string __tty_insert_flip_char tty_flip_buffer_push tty_ldisc_receive_buf +.. kernel-doc:: include/linux/tty_flip.h + :identifiers: tty_insert_flip_string_fixed_flag tty_insert_flip_string_flags + ---- Other Functions diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index c94df1a2d7f8..94a88dc05a54 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -303,82 +303,42 @@ int tty_buffer_request_room(struct tty_port *port, size_t size) } EXPORT_SYMBOL_GPL(tty_buffer_request_room); -/** - * tty_insert_flip_string_fixed_flag - add characters to the tty buffer - * @port: tty port - * @chars: characters - * @flag: flag value for each character - * @size: size - * - * Queue a series of bytes to the tty buffering. All the characters passed are - * marked with the supplied flag. - * - * Returns: the number added. - */ -int tty_insert_flip_string_fixed_flag(struct tty_port *port, const u8 *chars, - u8 flag, size_t size) +int __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, + const u8 *flags, bool mutable_flags, + size_t size) { + bool need_flags = mutable_flags || flags[0] != TTY_NORMAL; int copied = 0; - bool flags = flag != TTY_NORMAL; do { int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); - int space = __tty_buffer_request_room(port, goal, flags); + int space = __tty_buffer_request_room(port, goal, need_flags); struct tty_buffer *tb = port->buf.tail; if (unlikely(space == 0)) break; - memcpy(char_buf_ptr(tb, tb->used), chars, space); - if (tb->flags) - memset(flag_buf_ptr(tb, tb->used), flag, space); - tb->used += space; - copied += space; - chars += space; - /* There is a small chance that we need to split the data over - * several buffers. If this is the case we must loop. - */ - } while (unlikely(size > copied)); - return copied; -} -EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); -/** - * tty_insert_flip_string_flags - add characters to the tty buffer - * @port: tty port - * @chars: characters - * @flags: flag bytes - * @size: size - * - * Queue a series of bytes to the tty buffering. For each character the flags - * array indicates the status of the character. - * - * Returns: the number added. - */ -int tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, - const u8 *flags, size_t size) -{ - int copied = 0; + memcpy(char_buf_ptr(tb, tb->used), chars, space); - do { - int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); - int space = tty_buffer_request_room(port, goal); - struct tty_buffer *tb = port->buf.tail; + if (mutable_flags) { + memcpy(flag_buf_ptr(tb, tb->used), flags, space); + flags += space; + } else if (tb->flags) { + memset(flag_buf_ptr(tb, tb->used), flags[0], space); + } - if (unlikely(space == 0)) - break; - memcpy(char_buf_ptr(tb, tb->used), chars, space); - memcpy(flag_buf_ptr(tb, tb->used), flags, space); tb->used += space; copied += space; chars += space; - flags += space; + /* There is a small chance that we need to split the data over * several buffers. If this is the case we must loop. */ } while (unlikely(size > copied)); + return copied; } -EXPORT_SYMBOL(tty_insert_flip_string_flags); +EXPORT_SYMBOL(__tty_insert_flip_string_flags); /** * __tty_insert_flip_char - add one character to the tty buffer diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index d33aed2172c7..8b781f709605 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -10,14 +10,52 @@ struct tty_ldisc; int tty_buffer_set_limit(struct tty_port *port, int limit); unsigned int tty_buffer_space_avail(struct tty_port *port); int tty_buffer_request_room(struct tty_port *port, size_t size); -int tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, - const u8 *flags, size_t size); -int tty_insert_flip_string_fixed_flag(struct tty_port *port, const u8 *chars, - u8 flag, size_t size); +int __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, + const u8 *flags, bool mutable_flags, + size_t size); int tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size); void tty_flip_buffer_push(struct tty_port *port); int __tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag); +/** + * tty_insert_flip_string_fixed_flag - add characters to the tty buffer + * @port: tty port + * @chars: characters + * @flag: flag value for each character + * @size: size + * + * Queue a series of bytes to the tty buffering. All the characters passed are + * marked with the supplied flag. + * + * Returns: the number added. + */ +static inline int tty_insert_flip_string_fixed_flag(struct tty_port *port, + const u8 *chars, u8 flag, + size_t size) +{ + return __tty_insert_flip_string_flags(port, chars, &flag, false, size); +} + +/** + * tty_insert_flip_string_flags - add characters to the tty buffer + * @port: tty port + * @chars: characters + * @flags: flag bytes + * @size: size + * + * Queue a series of bytes to the tty buffering. For each character the flags + * array indicates the status of the character. + * + * Returns: the number added. + */ +static inline int tty_insert_flip_string_flags(struct tty_port *port, + const u8 *chars, const u8 *flags, + size_t size) +{ + return __tty_insert_flip_string_flags(port, chars, flags, true, size); +} + + static inline int tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) { struct tty_buffer *tb = port->buf.tail; -- cgit v1.2.3 From 4a8d99a409d3d194527674a896362992a171cd7b Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:24 +0200 Subject: tty: tty_buffer: warn if losing flags in __tty_insert_flip_string_flags() And add a WARN_ON_ONCE(need_flags) to make sure we are not losing flags in __tty_insert_flip_string_flags(). Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-5-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 94a88dc05a54..c101b4ab737e 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -325,6 +325,9 @@ int __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, flags += space; } else if (tb->flags) { memset(flag_buf_ptr(tb, tb->used), flags[0], space); + } else { + /* tb->flags should be available once requested */ + WARN_ON_ONCE(need_flags); } tb->used += space; -- cgit v1.2.3 From 6144922e17677204cbead4ee544699af69785a84 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:25 +0200 Subject: tty: tty_buffer: switch insert functions to size_t All the functions accept size_t as a size argument. They finally return the same size (or less). It is quite unexpected that they return a signed value and can confuse users to check for negative values. Instead, return the same size_t as accepted to make clear we return values >= 0, where zero in fact means failure. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-6-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 12 ++++++------ include/linux/tty_flip.h | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index c101b4ab737e..598891e53031 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -303,16 +303,16 @@ int tty_buffer_request_room(struct tty_port *port, size_t size) } EXPORT_SYMBOL_GPL(tty_buffer_request_room); -int __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, - const u8 *flags, bool mutable_flags, - size_t size) +size_t __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, + const u8 *flags, bool mutable_flags, + size_t size) { bool need_flags = mutable_flags || flags[0] != TTY_NORMAL; - int copied = 0; + size_t copied = 0; do { - int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); - int space = __tty_buffer_request_room(port, goal, need_flags); + size_t goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); + size_t space = __tty_buffer_request_room(port, goal, need_flags); struct tty_buffer *tb = port->buf.tail; if (unlikely(space == 0)) diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index 8b781f709605..569747364ae5 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -10,9 +10,9 @@ struct tty_ldisc; int tty_buffer_set_limit(struct tty_port *port, int limit); unsigned int tty_buffer_space_avail(struct tty_port *port); int tty_buffer_request_room(struct tty_port *port, size_t size); -int __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, - const u8 *flags, bool mutable_flags, - size_t size); +size_t __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, + const u8 *flags, bool mutable_flags, + size_t size); int tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size); void tty_flip_buffer_push(struct tty_port *port); int __tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag); @@ -29,9 +29,9 @@ int __tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag); * * Returns: the number added. */ -static inline int tty_insert_flip_string_fixed_flag(struct tty_port *port, - const u8 *chars, u8 flag, - size_t size) +static inline size_t tty_insert_flip_string_fixed_flag(struct tty_port *port, + const u8 *chars, u8 flag, + size_t size) { return __tty_insert_flip_string_flags(port, chars, &flag, false, size); } @@ -48,15 +48,15 @@ static inline int tty_insert_flip_string_fixed_flag(struct tty_port *port, * * Returns: the number added. */ -static inline int tty_insert_flip_string_flags(struct tty_port *port, - const u8 *chars, const u8 *flags, - size_t size) +static inline size_t tty_insert_flip_string_flags(struct tty_port *port, + const u8 *chars, + const u8 *flags, size_t size) { return __tty_insert_flip_string_flags(port, chars, flags, true, size); } -static inline int tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) +static inline size_t tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) { struct tty_buffer *tb = port->buf.tail; int change; @@ -71,8 +71,8 @@ static inline int tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) return __tty_insert_flip_char(port, ch, flag); } -static inline int tty_insert_flip_string(struct tty_port *port, - const u8 *chars, size_t size) +static inline size_t tty_insert_flip_string(struct tty_port *port, + const u8 *chars, size_t size) { return tty_insert_flip_string_fixed_flag(port, chars, TTY_NORMAL, size); } -- cgit v1.2.3 From 2ce2983c24c11beaeb6ef6da93bf7228679bd08b Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:26 +0200 Subject: tty: tty_buffer: let tty_prepare_flip_string() return size_t The same as in the previous patch, tty_prepare_flip_string() accepts size_t as an size argument. It returns the same size (or less). It is unexpected that it returns a signed value and can confuse users to check for negative values. Instead, return the same size_t as accepted to make clear we return values >= 0, where zero in fact means failure. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-7-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 5 +++-- include/linux/tty_flip.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 598891e53031..4f84466498f7 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -383,9 +383,9 @@ EXPORT_SYMBOL(__tty_insert_flip_char); * Returns: the length available and buffer pointer (@chars) to the space which * is now allocated and accounted for as ready for normal characters. */ -int tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size) +size_t tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size) { - int space = __tty_buffer_request_room(port, size, false); + size_t space = __tty_buffer_request_room(port, size, false); if (likely(space)) { struct tty_buffer *tb = port->buf.tail; @@ -395,6 +395,7 @@ int tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size) memset(flag_buf_ptr(tb, tb->used), TTY_NORMAL, space); tb->used += space; } + return space; } EXPORT_SYMBOL_GPL(tty_prepare_flip_string); diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index 569747364ae5..efd03d9c11f8 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -13,7 +13,7 @@ int tty_buffer_request_room(struct tty_port *port, size_t size); size_t __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, const u8 *flags, bool mutable_flags, size_t size); -int tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size); +size_t tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size); void tty_flip_buffer_push(struct tty_port *port); int __tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag); -- cgit v1.2.3 From b49a0ff7328f5f9acfd027906f4c7d313a225361 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:27 +0200 Subject: tty: tty_buffer: use __tty_insert_flip_string_flags() in tty_insert_flip_char() Use __tty_insert_flip_string_flags() for the slow path of tty_insert_flip_char(). The former is generic enough, so there is no reason to reimplement the injection once again. So now we have a single function stuffing into tty buffers. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-8-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/tty/tty_buffer.rst | 3 ++- drivers/tty/tty_buffer.c | 26 -------------------------- include/linux/tty_flip.h | 12 +++++++++--- 3 files changed, 11 insertions(+), 30 deletions(-) diff --git a/Documentation/driver-api/tty/tty_buffer.rst b/Documentation/driver-api/tty/tty_buffer.rst index 774dc119c312..4b5ca1776d4f 100644 --- a/Documentation/driver-api/tty/tty_buffer.rst +++ b/Documentation/driver-api/tty/tty_buffer.rst @@ -15,11 +15,12 @@ Flip Buffer Management ====================== .. kernel-doc:: drivers/tty/tty_buffer.c - :identifiers: tty_prepare_flip_string __tty_insert_flip_char + :identifiers: tty_prepare_flip_string tty_flip_buffer_push tty_ldisc_receive_buf .. kernel-doc:: include/linux/tty_flip.h :identifiers: tty_insert_flip_string_fixed_flag tty_insert_flip_string_flags + tty_insert_flip_char ---- diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 4f84466498f7..e162318d6c31 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -343,32 +343,6 @@ size_t __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, } EXPORT_SYMBOL(__tty_insert_flip_string_flags); -/** - * __tty_insert_flip_char - add one character to the tty buffer - * @port: tty port - * @ch: character - * @flag: flag byte - * - * Queue a single byte @ch to the tty buffering, with an optional flag. This is - * the slow path of tty_insert_flip_char(). - */ -int __tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) -{ - struct tty_buffer *tb; - bool flags = flag != TTY_NORMAL; - - if (!__tty_buffer_request_room(port, 1, flags)) - return 0; - - tb = port->buf.tail; - if (tb->flags) - *flag_buf_ptr(tb, tb->used) = flag; - *char_buf_ptr(tb, tb->used++) = ch; - - return 1; -} -EXPORT_SYMBOL(__tty_insert_flip_char); - /** * tty_prepare_flip_string - make room for characters * @port: tty port diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index efd03d9c11f8..af4fce98f64e 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -15,7 +15,6 @@ size_t __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars, size_t size); size_t tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size); void tty_flip_buffer_push(struct tty_port *port); -int __tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag); /** * tty_insert_flip_string_fixed_flag - add characters to the tty buffer @@ -55,7 +54,14 @@ static inline size_t tty_insert_flip_string_flags(struct tty_port *port, return __tty_insert_flip_string_flags(port, chars, flags, true, size); } - +/** + * tty_insert_flip_char - add one character to the tty buffer + * @port: tty port + * @ch: character + * @flag: flag byte + * + * Queue a single byte @ch to the tty buffering, with an optional flag. + */ static inline size_t tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) { struct tty_buffer *tb = port->buf.tail; @@ -68,7 +74,7 @@ static inline size_t tty_insert_flip_char(struct tty_port *port, u8 ch, u8 flag) *char_buf_ptr(tb, tb->used++) = ch; return 1; } - return __tty_insert_flip_char(port, ch, flag); + return __tty_insert_flip_string_flags(port, &ch, &flag, false, 1); } static inline size_t tty_insert_flip_string(struct tty_port *port, -- cgit v1.2.3 From 64365743b366ae756d4e9c16a0b639960f417493 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:28 +0200 Subject: tty: tty_buffer: better types in __tty_buffer_request_room() * use bool for 'change' as it holds a result of a boolean. * use size_t for 'left', so it is the same as 'size' which it is compared to. Both are supposed to contain an unsigned value. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-9-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index e162318d6c31..414bb7f9155f 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -263,7 +263,8 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, { struct tty_bufhead *buf = &port->buf; struct tty_buffer *b, *n; - int left, change; + size_t left; + bool change; b = buf->tail; if (!b->flags) -- cgit v1.2.3 From 035197c908b57804b9407cf119d2c2fe5934ee00 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:29 +0200 Subject: tty: tty_buffer: initialize variables in initializers already It makes the code both more compact, and more understandable. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-10-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 414bb7f9155f..44c0adaec850 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -262,17 +262,10 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, bool flags) { struct tty_bufhead *buf = &port->buf; - struct tty_buffer *b, *n; - size_t left; - bool change; + struct tty_buffer *n, *b = buf->tail; + size_t left = (b->flags ? 1 : 2) * b->size - b->used; + bool change = !b->flags && flags; - b = buf->tail; - if (!b->flags) - left = 2 * b->size - b->used; - else - left = b->size - b->used; - - change = !b->flags && flags; if (change || left < size) { /* This is the slow path - looking for new buffers to use */ n = tty_buffer_alloc(port, size); -- cgit v1.2.3 From ebee41c8490aeb3ef2e7d25f5e97ce45c996da4d Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 16 Aug 2023 12:55:30 +0200 Subject: tty: tty_buffer: invert conditions in __tty_buffer_request_room() We are used to handle "bad" states in the 'if's in the kernel. Refactor (invert the two conditions in) __tty_buffer_request_room(), so that the code returns from the fast paths immediately instead of postponing to the heavy end of the function. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230816105530.3335-11-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 44c0adaec850..5f6d0cf67571 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -266,28 +266,28 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, size_t left = (b->flags ? 1 : 2) * b->size - b->used; bool change = !b->flags && flags; - if (change || left < size) { - /* This is the slow path - looking for new buffers to use */ - n = tty_buffer_alloc(port, size); - if (n != NULL) { - n->flags = flags; - buf->tail = n; - /* - * Paired w/ acquire in flush_to_ldisc() and lookahead_bufs() - * ensures they see all buffer data. - */ - smp_store_release(&b->commit, b->used); - /* - * Paired w/ acquire in flush_to_ldisc() and lookahead_bufs() - * ensures the latest commit value can be read before the head - * is advanced to the next buffer. - */ - smp_store_release(&b->next, n); - } else if (change) - size = 0; - else - size = left; - } + if (!change && left >= size) + return size; + + /* This is the slow path - looking for new buffers to use */ + n = tty_buffer_alloc(port, size); + if (n == NULL) + return change ? 0 : left; + + n->flags = flags; + buf->tail = n; + /* + * Paired w/ acquire in flush_to_ldisc() and lookahead_bufs() + * ensures they see all buffer data. + */ + smp_store_release(&b->commit, b->used); + /* + * Paired w/ acquire in flush_to_ldisc() and lookahead_bufs() + * ensures the latest commit value can be read before the head + * is advanced to the next buffer. + */ + smp_store_release(&b->next, n); + return size; } -- cgit v1.2.3 From 54b45ee8bd4228a7e3fdd1bbfa4e31fe87e1cbbf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 21 Aug 2023 11:38:57 +0300 Subject: serial: core: Remove unused PORT_* definitions For the last couple of years Linux kernel got rid of a few architectures and many platforms. Hence some PORT_* definitions in the serial_core.h become unused and redundant. Remove them for good. Removed IDs are checked for users against Debian Code Search engine. Hence safe to remove as there are no consumers found (only providers). While at it, add a note about 0-13, that are defined in the other file. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230821083857.1065282-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/serial_core.h | 43 +++------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 281fa286555c..d19dabd2c20d 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -25,6 +25,8 @@ /* * The type definitions. These are from Ted Ts'o's serial.h + * By historical reasons the values from 0 to 13 are defined + * in the include/uapi/linux/serial.h, do not define them here. */ #define PORT_NS16550A 14 #define PORT_XSCALE 15 @@ -94,15 +96,9 @@ #define PORT_SCIF 53 #define PORT_IRDA 54 -/* Samsung S3C2410 SoC and derivatives thereof */ -#define PORT_S3C2410 55 - /* SGI IP22 aka Indy / Challenge S / Indigo 2 */ #define PORT_IP22ZILOG 56 -/* Sharp LH7a40x -- an ARM9 SoC series */ -#define PORT_LH7A40X 57 - /* PPC CPM type number */ #define PORT_CPM 58 @@ -112,51 +108,27 @@ /* IBM icom */ #define PORT_ICOM 60 -/* Samsung S3C2440 SoC */ -#define PORT_S3C2440 61 - /* Motorola i.MX SoC */ #define PORT_IMX 62 -/* Marvell MPSC (obsolete unused) */ -#define PORT_MPSC 63 - /* TXX9 type number */ #define PORT_TXX9 64 -/* Samsung S3C2400 SoC */ -#define PORT_S3C2400 67 - -/* M32R SIO */ -#define PORT_M32R_SIO 68 - /*Digi jsm */ #define PORT_JSM 69 /* SUN4V Hypervisor Console */ #define PORT_SUNHV 72 -#define PORT_S3C2412 73 - /* Xilinx uartlite */ #define PORT_UARTLITE 74 -/* Blackfin bf5xx */ -#define PORT_BFIN 75 - /* Broadcom SB1250, etc. SOC */ #define PORT_SB1250_DUART 77 /* Freescale ColdFire */ #define PORT_MCF 78 -/* Blackfin SPORT */ -#define PORT_BFIN_SPORT 79 - -/* MN10300 on-chip UART numbers */ -#define PORT_MN10300 80 -#define PORT_MN10300_CTS 81 - #define PORT_SC26XX 82 /* SH-SCI */ @@ -164,9 +136,6 @@ #define PORT_S3C6400 84 -/* NWPSERIAL, now removed */ -#define PORT_NWPSERIAL 85 - /* MAX3100 */ #define PORT_MAX3100 86 @@ -225,13 +194,10 @@ /* ST ASC type numbers */ #define PORT_ASC 105 -/* Tilera TILE-Gx UART */ -#define PORT_TILEGX 106 - /* MEN 16z135 UART */ #define PORT_MEN_Z135 107 -/* SC16IS74xx */ +/* SC16IS7xx */ #define PORT_SC16IS7XX 108 /* MESON */ @@ -243,9 +209,6 @@ /* SPRD SERIAL */ #define PORT_SPRD 111 -/* Cris v10 / v32 SoC */ -#define PORT_CRIS 112 - /* STM32 USART */ #define PORT_STM32 113 -- cgit v1.2.3 From a031c77dfce4f201cf94d6704cca5535ef44cb04 Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 17 Aug 2023 11:32:23 +0200 Subject: tty: n_gsm: add restart flag to DLC specific ioctl config Currently, changing the parameters of a DLCI gives no direct control to the user whether this should trigger a channel reset or not. The decision is solely made by the driver based on the assumption which parameter changes are compatible or not. Therefore, the user has no means to perform an automatic channel reset after parameter configuration for non-conflicting changes. Add the parameter 'flags' to 'gsm_dlci_config' to force a channel reset after ioctl setting regardless of whether the changes made require this or not by setting this to 'GSM_FL_RESTART'. Note that 'GSM_FL_RESTART' is currently the only allow flag to allow additions here. Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20230817093231.2317-1-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 4 ++++ include/uapi/linux/gsmmux.h | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 31033663f964..27da795ca348 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2532,6 +2532,8 @@ static int gsm_dlci_config(struct gsm_dlci *dlci, struct gsm_dlci_config *dc, in return -EINVAL; if (dc->k > 7) return -EINVAL; + if (dc->flags & ~GSM_FL_RESTART) /* allow future extensions */ + return -EINVAL; /* * See what is needed for reconfiguration @@ -2546,6 +2548,8 @@ static int gsm_dlci_config(struct gsm_dlci *dlci, struct gsm_dlci_config *dc, in /* Requires care */ if (dc->priority != dlci->prio) need_restart = true; + if (dc->flags & GSM_FL_RESTART) + need_restart = true; if ((open && gsm->wait_config) || need_restart) need_open = true; diff --git a/include/uapi/linux/gsmmux.h b/include/uapi/linux/gsmmux.h index eb67884e5f38..e56e2d7ea6eb 100644 --- a/include/uapi/linux/gsmmux.h +++ b/include/uapi/linux/gsmmux.h @@ -2,10 +2,22 @@ #ifndef _LINUX_GSMMUX_H #define _LINUX_GSMMUX_H +#include #include #include #include +/* + * flags definition for n_gsm + * + * Used by: + * struct gsm_dlci_config.flags + */ +/* Forces a DLCI reset if set. Otherwise, a DLCI reset is only done if + * incompatible settings were provided. Always cleared on retrieval. + */ +#define GSM_FL_RESTART _BITUL(0) + struct gsm_config { unsigned int adaption; @@ -58,7 +70,8 @@ struct gsm_dlci_config { __u32 priority; /* Priority (0 for default value) */ __u32 i; /* Frame type (1 = UIH, 2 = UI) */ __u32 k; /* Window size (0 for default value) */ - __u32 reserved[8]; /* For future use, must be initialized to zero */ + __u32 flags; /* DLCI specific flags. */ + __u32 reserved[7]; /* For future use, must be initialized to zero */ }; #define GSMIOC_GETCONF_DLCI _IOWR('G', 7, struct gsm_dlci_config) -- cgit v1.2.3 From 901de5ac0ea92c63c4cd7be60f9ccbbacd623a3c Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 17 Aug 2023 11:32:24 +0200 Subject: tty: n_gsm: add missing description to structs in gsmmux.h Currently, all available structure fields in gsmmux.h except those for gsm_config are commented. Furthermore, no kernel doc comments are used. Fix this by adding appropriate comments to the not commented fields of gsm_config. Convert the comments of the other structs to kernel doc format. Note that 'mru' and 'mtu' refer to the size without basic/advanced option mode header and byte stuffing as defined in the standard in chapter 5.7.2. Link: https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20230817093231.2317-2-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/gsmmux.h | 104 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 20 deletions(-) diff --git a/include/uapi/linux/gsmmux.h b/include/uapi/linux/gsmmux.h index e56e2d7ea6eb..3bd6f03a8293 100644 --- a/include/uapi/linux/gsmmux.h +++ b/include/uapi/linux/gsmmux.h @@ -18,6 +18,28 @@ */ #define GSM_FL_RESTART _BITUL(0) +/** + * struct gsm_config - n_gsm basic configuration parameters + * + * This structure is used in combination with GSMIOC_GETCONF and GSMIOC_SETCONF + * to retrieve and set the basic parameters of an n_gsm ldisc. + * struct gsm_config_ext can be used to configure extended ldisc parameters. + * + * All timers are in units of 1/100th of a second. + * + * @adaption: Convergence layer type + * @encapsulation: Framing (0 = basic option, 1 = advanced option) + * @initiator: Initiator or responder + * @t1: Acknowledgment timer + * @t2: Response timer for multiplexer control channel + * @t3: Response timer for wake-up procedure + * @n2: Maximum number of retransmissions + * @mru: Maximum incoming frame payload size + * @mtu: Maximum outgoing frame payload size + * @k: Window size + * @i: Frame type (1 = UIH, 2 = UI) + * @unused: Can not be used + */ struct gsm_config { unsigned int adaption; @@ -31,18 +53,32 @@ struct gsm_config unsigned int mtu; unsigned int k; unsigned int i; - unsigned int unused[8]; /* Can not be used */ + unsigned int unused[8]; }; #define GSMIOC_GETCONF _IOR('G', 0, struct gsm_config) #define GSMIOC_SETCONF _IOW('G', 1, struct gsm_config) +/** + * struct gsm_netconfig - n_gsm network configuration parameters + * + * This structure is used in combination with GSMIOC_ENABLE_NET and + * GSMIOC_DISABLE_NET to enable or disable a network data connection + * over a mux virtual tty channel. This is for modems that support + * data connections with raw IP frames instead of PPP. + * + * @adaption: Adaption to use in network mode. + * @protocol: Protocol to use - only ETH_P_IP supported. + * @unused2: Can not be used. + * @if_name: Interface name format string. + * @unused: Can not be used. + */ struct gsm_netconfig { - unsigned int adaption; /* Adaption to use in network mode */ - unsigned short protocol;/* Protocol to use - only ETH_P_IP supported */ - unsigned short unused2; /* Can not be used */ - char if_name[IFNAMSIZ]; /* interface name format string */ - __u8 unused[28]; /* Can not be used */ + unsigned int adaption; + unsigned short protocol; + unsigned short unused2; + char if_name[IFNAMSIZ]; + __u8 unused[28]; }; #define GSMIOC_ENABLE_NET _IOW('G', 2, struct gsm_netconfig) @@ -51,27 +87,55 @@ struct gsm_netconfig { /* get the base tty number for a configured gsmmux tty */ #define GSMIOC_GETFIRST _IOR('G', 4, __u32) +/** + * struct gsm_config_ext - n_gsm extended configuration parameters + * + * This structure is used in combination with GSMIOC_GETCONF_EXT and + * GSMIOC_SETCONF_EXT to retrieve and set the extended parameters of an + * n_gsm ldisc. + * + * All timers are in units of 1/100th of a second. + * + * @keep_alive: Control channel keep-alive in 1/100th of a second (0 to disable). + * @wait_config: Wait for DLCI config before opening virtual link? + * @reserved: For future use, must be initialized to zero. + */ struct gsm_config_ext { - __u32 keep_alive; /* Control channel keep-alive in 1/100th of a - * second (0 to disable) - */ - __u32 wait_config; /* Wait for DLCI config before opening virtual link? */ - __u32 reserved[6]; /* For future use, must be initialized to zero */ + __u32 keep_alive; + __u32 wait_config; + __u32 reserved[6]; }; #define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext) #define GSMIOC_SETCONF_EXT _IOW('G', 6, struct gsm_config_ext) -/* Set channel accordingly before calling GSMIOC_GETCONF_DLCI. */ +/** + * struct gsm_dlci_config - n_gsm channel configuration parameters + * + * This structure is used in combination with GSMIOC_GETCONF_DLCI and + * GSMIOC_SETCONF_DLCI to retrieve and set the channel specific parameters + * of an n_gsm ldisc. + * + * Set the channel accordingly before calling GSMIOC_GETCONF_DLCI. + * + * @channel: DLCI (0 for the associated DLCI). + * @adaption: Convergence layer type. + * @mtu: Maximum transfer unit. + * @priority: Priority (0 for default value). + * @i: Frame type (1 = UIH, 2 = UI). + * @k: Window size (0 for default value). + * @flags: DLCI specific flags. + * @reserved: For future use, must be initialized to zero. + */ struct gsm_dlci_config { - __u32 channel; /* DLCI (0 for the associated DLCI) */ - __u32 adaption; /* Convergence layer type */ - __u32 mtu; /* Maximum transfer unit */ - __u32 priority; /* Priority (0 for default value) */ - __u32 i; /* Frame type (1 = UIH, 2 = UI) */ - __u32 k; /* Window size (0 for default value) */ - __u32 flags; /* DLCI specific flags. */ - __u32 reserved[7]; /* For future use, must be initialized to zero */ + __u32 channel; + __u32 adaption; + __u32 mtu; + __u32 priority; + __u32 i; + __u32 k; + __u32 flags; + __u32 reserved[7]; }; #define GSMIOC_GETCONF_DLCI _IOWR('G', 7, struct gsm_dlci_config) -- cgit v1.2.3 From e1c90bbb5f5178967d5d3c0917de847e88ebe398 Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 17 Aug 2023 11:32:25 +0200 Subject: tty: n_gsm: remove unneeded initialization of ret in gsm_dlci_config The variable 'ret' is not used before assignment from gsm_activate_mux(). Still it gets initialized to zero at declaration. Fix this as remarked in the link below by moving the declaration to the first assignment. Link: https://lore.kernel.org/all/b42bc4d1-cc9d-d115-c981-aaa053bdc59f@kernel.org/ Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20230817093231.2317-3-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 27da795ca348..a4df0a20f212 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3280,7 +3280,6 @@ static void gsm_copy_config_values(struct gsm_mux *gsm, static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) { - int ret = 0; int need_close = 0; int need_restart = 0; @@ -3359,7 +3358,7 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) * and removing from the mux array */ if (gsm->dead) { - ret = gsm_activate_mux(gsm); + int ret = gsm_activate_mux(gsm); if (ret) return ret; if (gsm->initiator) -- cgit v1.2.3 From a1ce6da0833b91355499568caf0f432074d91cee Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 17 Aug 2023 11:32:26 +0200 Subject: tty: n_gsm: add open_error counter to gsm_mux Extend the n_gsm link statistics by a failed link open counter in preparation for an upcoming patch which will expose these. This counter is increased whenever an attempt to open the control channel failed. This is true in the following cases: - new DLCI allocation failed - connection request (SAMB) with invalid CR flag has been received - connection response (UA) timed out - parameter negotiation timed out or failed Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20230817093231.2317-4-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index a4df0a20f212..68276a7e62a0 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -339,6 +339,7 @@ struct gsm_mux { unsigned long bad_fcs; unsigned long malformed; unsigned long io_error; + unsigned long open_error; unsigned long bad_size; unsigned long unsupported; }; @@ -1730,25 +1731,32 @@ static void gsm_control_negotiation(struct gsm_mux *gsm, unsigned int cr, struct gsm_dlci *dlci; struct gsm_dlci_param_bits *params; - if (dlen < sizeof(struct gsm_dlci_param_bits)) + if (dlen < sizeof(struct gsm_dlci_param_bits)) { + gsm->open_error++; return; + } /* Invalid DLCI? */ params = (struct gsm_dlci_param_bits *)data; addr = FIELD_GET(PN_D_FIELD_DLCI, params->d_bits); - if (addr == 0 || addr >= NUM_DLCI || !gsm->dlci[addr]) + if (addr == 0 || addr >= NUM_DLCI || !gsm->dlci[addr]) { + gsm->open_error++; return; + } dlci = gsm->dlci[addr]; /* Too late for parameter negotiation? */ - if ((!cr && dlci->state == DLCI_OPENING) || dlci->state == DLCI_OPEN) + if ((!cr && dlci->state == DLCI_OPENING) || dlci->state == DLCI_OPEN) { + gsm->open_error++; return; + } /* Process the received parameters */ if (gsm_process_negotiation(gsm, addr, cr, params) != 0) { /* Negotiation failed. Close the link. */ if (debug & DBG_ERRORS) pr_info("%s PN failed\n", __func__); + gsm->open_error++; gsm_dlci_close(dlci); return; } @@ -1768,6 +1776,7 @@ static void gsm_control_negotiation(struct gsm_mux *gsm, unsigned int cr, } else { if (debug & DBG_ERRORS) pr_info("%s PN in invalid state\n", __func__); + gsm->open_error++; } } @@ -2221,6 +2230,7 @@ static void gsm_dlci_t1(struct timer_list *t) dlci->retries--; mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); } else { + gsm->open_error++; gsm_dlci_begin_close(dlci); /* prevent half open link */ } break; @@ -2236,6 +2246,7 @@ static void gsm_dlci_t1(struct timer_list *t) dlci->mode = DLCI_MODE_ADM; gsm_dlci_open(dlci); } else { + gsm->open_error++; gsm_dlci_begin_close(dlci); /* prevent half open link */ } @@ -2757,12 +2768,16 @@ static void gsm_queue(struct gsm_mux *gsm) switch (gsm->control) { case SABM|PF: - if (cr == 1) + if (cr == 1) { + gsm->open_error++; goto invalid; + } if (dlci == NULL) dlci = gsm_dlci_alloc(gsm, address); - if (dlci == NULL) + if (dlci == NULL) { + gsm->open_error++; return; + } if (dlci->dead) gsm_response(gsm, address, DM|PF); else { -- cgit v1.2.3 From b99f51ba04035b2394cae008f9ac09563b012307 Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 17 Aug 2023 11:32:27 +0200 Subject: tty: n_gsm: increase malformed counter for malformed control frames The malformed counter in gsm_mux is already increased in case of errors detected in gsm_queue() and gsm1_receive(). gsm_dlci_command() also detects a case for a malformed frame but does not increase the malformed counter yet. Fix this by also increasing the gsm_mux malformed counter in case of a malformed frame in gsm_dlci_command(). Note that the malformed counter is not yet exposed and only set internally. Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20230817093231.2317-5-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 68276a7e62a0..2dc5bf14da2d 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2455,8 +2455,10 @@ static void gsm_dlci_command(struct gsm_dlci *dlci, const u8 *data, int len) data += dlen; /* Malformed command? */ - if (clen > len) + if (clen > len) { + dlci->gsm->malformed++; return; + } if (command & 1) gsm_control_message(dlci->gsm, command, data, clen); -- cgit v1.2.3 From e74c048ae4c8ff452f3837cb9c55f051f219231b Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 17 Aug 2023 11:32:28 +0200 Subject: tty: n_gsm: increase gsm_mux unsupported counted where appropriate The structure gsm_mux contains the 'unsupported' field. However, there is currently no place in the code which increases this counter. Increase the 'unsupported' statistics counter in the following case: - an unsupported frame type has been requested by the peer via parameter negotiation - a control frame with an unsupported but known command has been received Note that we have no means to detect an inconsistent/unsupported adaptation sufficient accuracy as this changes the structure of the UI/UIH frames. E.g. a one byte header is added in case of convergence layer type 2 instead of 1 and contains the modem signal octet with the state of the signal lines. There is no checksum or other value which indicates of this field is correct or should be present. Therefore, we can only assume protocol correctness here. See also 'gsm_dlci_data()' where this is handled. Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20230817093231.2317-6-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 2dc5bf14da2d..c7ce014e6a21 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1590,6 +1590,7 @@ static int gsm_process_negotiation(struct gsm_mux *gsm, unsigned int addr, if (debug & DBG_ERRORS) pr_info("%s unsupported I frame request in PN\n", __func__); + gsm->unsupported++; return -EINVAL; default: if (debug & DBG_ERRORS) @@ -1897,6 +1898,8 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, /* Optional unsupported commands */ case CMD_RPN: /* Remote port negotiation */ case CMD_SNC: /* Service negotiation command */ + gsm->unsupported++; + fallthrough; default: /* Reply to bad commands with an NSC */ buf[0] = command; -- cgit v1.2.3 From 5767712668b80737e6ed714015a8840dbedad25e Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 17 Aug 2023 11:32:29 +0200 Subject: tty: n_gsm: cleanup gsm_control_command and gsm_control_reply There are multiple places in gsm_control_command and gsm_control_reply that derive the specific DLCI handle directly out of the DLCI table in gsm. Add a local variable which holds this handle and use it instead to improve code readability. Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20230817093231.2317-7-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c7ce014e6a21..68f4e0de9f0d 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1451,15 +1451,16 @@ static int gsm_control_command(struct gsm_mux *gsm, int cmd, const u8 *data, int dlen) { struct gsm_msg *msg; + struct gsm_dlci *dlci = gsm->dlci[0]; - msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->dlci[0]->ftype); + msg = gsm_data_alloc(gsm, 0, dlen + 2, dlci->ftype); if (msg == NULL) return -ENOMEM; msg->data[0] = (cmd << 1) | CR | EA; /* Set C/R */ msg->data[1] = (dlen << 1) | EA; memcpy(msg->data + 2, data, dlen); - gsm_data_queue(gsm->dlci[0], msg); + gsm_data_queue(dlci, msg); return 0; } @@ -1478,14 +1479,15 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, const u8 *data, int dlen) { struct gsm_msg *msg; + struct gsm_dlci *dlci = gsm->dlci[0]; - msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->dlci[0]->ftype); + msg = gsm_data_alloc(gsm, 0, dlen + 2, dlci->ftype); if (msg == NULL) return; msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */ msg->data[1] = (dlen << 1) | EA; memcpy(msg->data + 2, data, dlen); - gsm_data_queue(gsm->dlci[0], msg); + gsm_data_queue(dlci, msg); } /** -- cgit v1.2.3 From e112ec4202b154fa7409d388d77151804e462876 Mon Sep 17 00:00:00 2001 From: Daniel Starke Date: Thu, 17 Aug 2023 11:32:31 +0200 Subject: tty: n_gsm: add restart flag to extended ioctl config Currently, changing the parameters of the n_gsm mux gives no direct control to the user whether this should trigger a mux reset or not. The decision is solely made by the driver based on the assumption which parameter changes are compatible or not. Therefore, the user has no means to perform an automatic mux reset after parameter configuration for non-conflicting changes. Add the parameter 'flags' to 'gsm_config_ext' to force a mux reset after ioctl setting regardless of whether the changes made require this or not by setting this to 'GSM_FL_RESTART'. This is done similar to 'GSM_FL_RESTART' in gsm_dlci_config.flags. Note that 'GSM_FL_RESTART' is currently the only allowed flag to allow additions here. Signed-off-by: Daniel Starke Link: https://lore.kernel.org/r/20230817093231.2317-9-daniel.starke@siemens.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 23 +++++++++++++++++++++++ include/uapi/linux/gsmmux.h | 5 ++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 68f4e0de9f0d..b3550ff9c494 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3399,6 +3399,7 @@ static void gsm_copy_config_ext_values(struct gsm_mux *gsm, static int gsm_config_ext(struct gsm_mux *gsm, struct gsm_config_ext *ce) { + bool need_restart = false; unsigned int i; /* @@ -3408,6 +3409,20 @@ static int gsm_config_ext(struct gsm_mux *gsm, struct gsm_config_ext *ce) for (i = 0; i < ARRAY_SIZE(ce->reserved); i++) if (ce->reserved[i]) return -EINVAL; + if (ce->flags & ~GSM_FL_RESTART) + return -EINVAL; + + /* Requires care */ + if (ce->flags & GSM_FL_RESTART) + need_restart = true; + + /* + * Close down what is needed, restart and initiate the new + * configuration. On the first time there is no DLCI[0] + * and closing or cleaning up is not necessary. + */ + if (need_restart) + gsm_cleanup_mux(gsm, true); /* * Setup the new configuration values @@ -3415,6 +3430,14 @@ static int gsm_config_ext(struct gsm_mux *gsm, struct gsm_config_ext *ce) gsm->wait_config = ce->wait_config ? true : false; gsm->keep_alive = ce->keep_alive; + if (gsm->dead) { + int ret = gsm_activate_mux(gsm); + if (ret) + return ret; + if (gsm->initiator) + gsm_dlci_begin_open(gsm->dlci[0]); + } + return 0; } diff --git a/include/uapi/linux/gsmmux.h b/include/uapi/linux/gsmmux.h index 3bd6f03a8293..4c878d84dbda 100644 --- a/include/uapi/linux/gsmmux.h +++ b/include/uapi/linux/gsmmux.h @@ -11,6 +11,7 @@ * flags definition for n_gsm * * Used by: + * struct gsm_config_ext.flags * struct gsm_dlci_config.flags */ /* Forces a DLCI reset if set. Otherwise, a DLCI reset is only done if @@ -98,12 +99,14 @@ struct gsm_netconfig { * * @keep_alive: Control channel keep-alive in 1/100th of a second (0 to disable). * @wait_config: Wait for DLCI config before opening virtual link? + * @flags: Mux specific flags. * @reserved: For future use, must be initialized to zero. */ struct gsm_config_ext { __u32 keep_alive; __u32 wait_config; - __u32 reserved[6]; + __u32 flags; + __u32 reserved[5]; }; #define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext) -- cgit v1.2.3 From db89728abad5ab6b8f30349142897bd55f1f5b00 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Tue, 8 Aug 2023 18:19:01 +0200 Subject: serial: stm32: avoid clearing DMAT bit during transfer It's rather advised to rely on DMA pause / resume instead of clearing/setting DMA request enable bit for the same purpose. Some DMA request/acknowledge race may encountered by doing so. We prefer to use dmaengine_pause and resume instead to pause a dma transfer when it is necessary. It is also safer to close DMA before reset DMAT in stm32_usart_shutdown. Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20230808161906.178996-2-valentin.caron@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 76 +++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index be47cd343cf6..2f9672ba4ed3 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -506,13 +506,6 @@ static bool stm32_usart_tx_dma_started(struct stm32_port *stm32_port) return stm32_port->tx_dma_busy; } -static bool stm32_usart_tx_dma_enabled(struct stm32_port *stm32_port) -{ - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; - - return !!(readl_relaxed(stm32_port->port.membase + ofs->cr3) & USART_CR3_DMAT); -} - static void stm32_usart_tx_dma_complete(void *arg) { struct uart_port *port = arg; @@ -591,9 +584,6 @@ static void stm32_usart_transmit_chars_pio(struct uart_port *port) const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; struct circ_buf *xmit = &port->state->xmit; - if (stm32_usart_tx_dma_enabled(stm32_port)) - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); - while (!uart_circ_empty(xmit)) { /* Check that TDR is empty before filling FIFO */ if (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE)) @@ -616,10 +606,16 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port) struct circ_buf *xmit = &port->state->xmit; struct dma_async_tx_descriptor *desc = NULL; unsigned int count; + int ret; if (stm32_usart_tx_dma_started(stm32port)) { - if (!stm32_usart_tx_dma_enabled(stm32port)) - stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAT); + if (dmaengine_tx_status(stm32port->tx_ch, + stm32port->tx_ch->cookie, + NULL) == DMA_PAUSED) { + ret = dmaengine_resume(stm32port->tx_ch); + if (ret < 0) + goto dma_err; + } return; } @@ -664,11 +660,9 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port) desc->callback_param = port; /* Push current DMA TX transaction in the pending queue */ - if (dma_submit_error(dmaengine_submit(desc))) { - /* dma no yet started, safe to free resources */ - stm32_usart_tx_dma_terminate(stm32port); - goto fallback_err; - } + /* DMA no yet started, safe to free resources */ + if (dma_submit_error(dmaengine_submit(desc))) + goto dma_err; /* Issue pending DMA TX requests */ dma_async_issue_pending(stm32port->tx_ch); @@ -679,6 +673,10 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port) return; +dma_err: + dev_err(port->dev, "DMA failed with error code: %d\n", ret); + stm32_usart_tx_dma_terminate(stm32port); + fallback_err: stm32_usart_transmit_chars_pio(port); } @@ -701,9 +699,15 @@ static void stm32_usart_transmit_chars(struct uart_port *port) if (port->x_char) { if (stm32_usart_tx_dma_started(stm32_port) && - stm32_usart_tx_dma_enabled(stm32_port)) - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); - + dmaengine_tx_status(stm32_port->tx_ch, + stm32_port->tx_ch->cookie, + NULL) == DMA_IN_PROGRESS) { + ret = dmaengine_pause(stm32_port->tx_ch); + if (ret < 0) { + dev_err(port->dev, "DMA failed with error code: %d\n", ret); + stm32_usart_tx_dma_terminate(stm32_port); + } + } /* Check that TDR is empty before filling FIFO */ ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, @@ -716,8 +720,14 @@ static void stm32_usart_transmit_chars(struct uart_port *port) writel_relaxed(port->x_char, port->membase + ofs->tdr); port->x_char = 0; port->icount.tx++; - if (stm32_usart_tx_dma_started(stm32_port)) - stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAT); + + if (stm32_usart_tx_dma_started(stm32_port)) { + ret = dmaengine_resume(stm32_port->tx_ch); + if (ret < 0) { + dev_err(port->dev, "DMA failed with error code: %d\n", ret); + stm32_usart_tx_dma_terminate(stm32_port); + } + } return; } @@ -850,11 +860,16 @@ static void stm32_usart_disable_ms(struct uart_port *port) static void stm32_usart_stop_tx(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + int ret; stm32_usart_tx_interrupt_disable(port); - if (stm32_usart_tx_dma_started(stm32_port) && stm32_usart_tx_dma_enabled(stm32_port)) - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); + if (stm32_usart_tx_dma_started(stm32_port)) { + ret = dmaengine_pause(stm32_port->tx_ch); + if (ret < 0) { + dev_err(port->dev, "DMA failed with error code: %d\n", ret); + stm32_usart_tx_dma_terminate(stm32_port); + } + } stm32_usart_rs485_rts_disable(port); } @@ -878,12 +893,9 @@ static void stm32_usart_start_tx(struct uart_port *port) static void stm32_usart_flush_buffer(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; - if (stm32_port->tx_ch) { + if (stm32_port->tx_ch) stm32_usart_tx_dma_terminate(stm32_port); - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); - } } /* Throttle the remote when input buffer is about to overflow. */ @@ -1042,12 +1054,12 @@ static void stm32_usart_shutdown(struct uart_port *port) u32 val, isr; int ret; - if (stm32_usart_tx_dma_enabled(stm32_port)) - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); - if (stm32_usart_tx_dma_started(stm32_port)) stm32_usart_tx_dma_terminate(stm32_port); + if (stm32_port->tx_ch) + stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); + /* Disable modem control interrupts */ stm32_usart_disable_ms(port); -- cgit v1.2.3 From 00bc5e8fc91743753a3ac9de1e9567e844ae3967 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Tue, 8 Aug 2023 18:19:02 +0200 Subject: serial: stm32: use DMAT as a configuration bit DMAT is a configuration bit so it should be set at the startup of uart port and not when a DMA transfer begins. This patch move set of DMAT into set_termios and remove DMAT reset except in shutdown. Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20230808161906.178996-3-valentin.caron@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 2f9672ba4ed3..a1585aa1ceb0 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -510,10 +510,8 @@ static void stm32_usart_tx_dma_complete(void *arg) { struct uart_port *port = arg; struct stm32_port *stm32port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32port->info->ofs; unsigned long flags; - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); stm32_usart_tx_dma_terminate(stm32port); /* Let's see if we have pending data to send */ @@ -602,7 +600,6 @@ static void stm32_usart_transmit_chars_pio(struct uart_port *port) static void stm32_usart_transmit_chars_dma(struct uart_port *port) { struct stm32_port *stm32port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32port->info->ofs; struct circ_buf *xmit = &port->state->xmit; struct dma_async_tx_descriptor *desc = NULL; unsigned int count; @@ -667,8 +664,6 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port) /* Issue pending DMA TX requests */ dma_async_issue_pending(stm32port->tx_ch); - stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAT); - uart_xmit_advance(port, count); return; @@ -1270,6 +1265,9 @@ static void stm32_usart_set_termios(struct uart_port *port, cr3 |= USART_CR3_DDRE; } + if (stm32_port->tx_ch) + cr3 |= USART_CR3_DMAT; + if (rs485conf->flags & SER_RS485_ENABLED) { stm32_usart_config_reg_rs485(&cr1, &cr3, rs485conf->delay_rts_before_send, -- cgit v1.2.3 From 00d1f9c6af0d4c8b1ae8b9aecbd8aa6295b4abf2 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Tue, 8 Aug 2023 18:19:03 +0200 Subject: serial: stm32: modify parameter and rename stm32_usart_rx_dma_enabled Rename stm32_usart_rx_dma_enabled to stm32_usart_rx_dma_started in order to match with stm32_usart_tx_dma_started. Modify argument of stm32_usart_rx_dma_started from uart_port structure to stm32_port structure to match with stm32_usart_tx_dma_started. Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20230808161906.178996-4-valentin.caron@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index a1585aa1ceb0..3471e23bb02f 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -289,9 +289,9 @@ static int stm32_usart_init_rs485(struct uart_port *port, return uart_get_rs485_mode(port); } -static bool stm32_usart_rx_dma_enabled(struct uart_port *port) +static bool stm32_usart_rx_dma_started(struct stm32_port *stm32_port) { - struct stm32_port *stm32_port = to_stm32_port(port); + struct uart_port *port = &stm32_port->port; const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; if (!stm32_port->rx_ch) @@ -310,7 +310,7 @@ static bool stm32_usart_pending_rx_pio(struct uart_port *port, u32 *sr) /* Get pending characters in RDR or FIFO */ if (*sr & USART_SR_RXNE) { /* Get all pending characters from the RDR or the FIFO when using interrupts */ - if (!stm32_usart_rx_dma_enabled(port)) + if (!stm32_usart_rx_dma_started(stm32_port)) return true; /* Handle only RX data errors when using DMA */ @@ -455,7 +455,7 @@ static unsigned int stm32_usart_receive_chars(struct uart_port *port, bool force u32 sr; unsigned int size = 0; - if (stm32_usart_rx_dma_enabled(port) || force_dma_flush) { + if (stm32_usart_rx_dma_started(stm32_port) || force_dma_flush) { rx_dma_status = dmaengine_tx_status(stm32_port->rx_ch, stm32_port->rx_ch->cookie, &stm32_port->rx_dma_state); @@ -789,8 +789,8 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) * line has been masked by HW and rx data are stacking in FIFO. */ if (!stm32_port->throttled) { - if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_enabled(port)) || - ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_enabled(port))) { + if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_started(stm32_port)) || + ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_started(stm32_port))) { spin_lock(&port->lock); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq(port); @@ -806,7 +806,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) } /* Receiver timeout irq for DMA RX */ - if (stm32_usart_rx_dma_enabled(port) && !stm32_port->throttled) { + if (stm32_usart_rx_dma_started(stm32_port) && !stm32_port->throttled) { spin_lock(&port->lock); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq(port); @@ -906,7 +906,7 @@ static void stm32_usart_throttle(struct uart_port *port) * Disable DMA request line if enabled, so the RX data gets queued into the FIFO. * Hardware flow control is triggered when RX FIFO is full. */ - if (stm32_usart_rx_dma_enabled(port)) + if (stm32_usart_rx_dma_started(stm32_port)) stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); stm32_usart_clr_bits(port, ofs->cr1, stm32_port->cr1_irq); -- cgit v1.2.3 From 7f28bcea824e4fb192214c6121161053efe738a8 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Tue, 8 Aug 2023 18:19:04 +0200 Subject: serial: stm32: group dma pause/resume error handling into single function Create new function "stm32_usart_dma_pause_resume" that called dmaengine_ pause/resume and in case of error, terminate dma transaction. Two other functions are created to facilitate the use of stm32_usart_dma _pause_resume : stm32_usart_tx_dma_pause, stm32_usart_tx_dma_resume. Equivalent functions for rx will be added in future patch. Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20230808161906.178996-5-valentin.caron@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 127 +++++++++++++++++++++++++-------------- drivers/tty/serial/stm32-usart.h | 1 + 2 files changed, 83 insertions(+), 45 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 3471e23bb02f..0dae05a7abe6 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -290,14 +290,40 @@ static int stm32_usart_init_rs485(struct uart_port *port, } static bool stm32_usart_rx_dma_started(struct stm32_port *stm32_port) +{ + return stm32_port->rx_ch ? stm32_port->rx_dma_busy : false; +} + +static void stm32_usart_rx_dma_terminate(struct stm32_port *stm32_port) +{ + dmaengine_terminate_async(stm32_port->rx_ch); + stm32_port->rx_dma_busy = false; +} + +static int stm32_usart_dma_pause_resume(struct stm32_port *stm32_port, + struct dma_chan *chan, + enum dma_status expected_status, + int dmaengine_pause_or_resume(struct dma_chan *), + bool stm32_usart_xx_dma_started(struct stm32_port *), + void stm32_usart_xx_dma_terminate(struct stm32_port *)) { struct uart_port *port = &stm32_port->port; - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + enum dma_status dma_status; + int ret; + + if (!stm32_usart_xx_dma_started(stm32_port)) + return -EPERM; - if (!stm32_port->rx_ch) - return false; + dma_status = dmaengine_tx_status(chan, chan->cookie, NULL); + if (dma_status != expected_status) + return -EAGAIN; - return !!(readl_relaxed(port->membase + ofs->cr3) & USART_CR3_DMAR); + ret = dmaengine_pause_or_resume(chan); + if (ret) { + dev_err(port->dev, "DMA failed with error code: %d\n", ret); + stm32_usart_xx_dma_terminate(stm32_port); + } + return ret; } /* Return true when data is pending (in pio mode), and false when no data is pending. */ @@ -475,7 +501,7 @@ static unsigned int stm32_usart_receive_chars(struct uart_port *port, bool force } } else { /* Disable RX DMA */ - dmaengine_terminate_async(stm32_port->rx_ch); + stm32_usart_rx_dma_terminate(stm32_port); stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); /* Fall back to interrupt mode */ dev_dbg(port->dev, "DMA error, fallback to irq mode\n"); @@ -506,6 +532,22 @@ static bool stm32_usart_tx_dma_started(struct stm32_port *stm32_port) return stm32_port->tx_dma_busy; } +static int stm32_usart_tx_dma_pause(struct stm32_port *stm32_port) +{ + return stm32_usart_dma_pause_resume(stm32_port, stm32_port->tx_ch, + DMA_IN_PROGRESS, dmaengine_pause, + stm32_usart_tx_dma_started, + stm32_usart_tx_dma_terminate); +} + +static int stm32_usart_tx_dma_resume(struct stm32_port *stm32_port) +{ + return stm32_usart_dma_pause_resume(stm32_port, stm32_port->tx_ch, + DMA_PAUSED, dmaengine_resume, + stm32_usart_tx_dma_started, + stm32_usart_tx_dma_terminate); +} + static void stm32_usart_tx_dma_complete(void *arg) { struct uart_port *port = arg; @@ -606,13 +648,9 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port) int ret; if (stm32_usart_tx_dma_started(stm32port)) { - if (dmaengine_tx_status(stm32port->tx_ch, - stm32port->tx_ch->cookie, - NULL) == DMA_PAUSED) { - ret = dmaengine_resume(stm32port->tx_ch); - if (ret < 0) - goto dma_err; - } + ret = stm32_usart_tx_dma_resume(stm32port); + if (ret < 0 && ret != -EAGAIN) + goto fallback_err; return; } @@ -658,8 +696,12 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port) /* Push current DMA TX transaction in the pending queue */ /* DMA no yet started, safe to free resources */ - if (dma_submit_error(dmaengine_submit(desc))) - goto dma_err; + ret = dma_submit_error(dmaengine_submit(desc)); + if (ret) { + dev_err(port->dev, "DMA failed with error code: %d\n", ret); + stm32_usart_tx_dma_terminate(stm32port); + goto fallback_err; + } /* Issue pending DMA TX requests */ dma_async_issue_pending(stm32port->tx_ch); @@ -668,10 +710,6 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port) return; -dma_err: - dev_err(port->dev, "DMA failed with error code: %d\n", ret); - stm32_usart_tx_dma_terminate(stm32port); - fallback_err: stm32_usart_transmit_chars_pio(port); } @@ -693,16 +731,9 @@ static void stm32_usart_transmit_chars(struct uart_port *port) } if (port->x_char) { - if (stm32_usart_tx_dma_started(stm32_port) && - dmaengine_tx_status(stm32_port->tx_ch, - stm32_port->tx_ch->cookie, - NULL) == DMA_IN_PROGRESS) { - ret = dmaengine_pause(stm32_port->tx_ch); - if (ret < 0) { - dev_err(port->dev, "DMA failed with error code: %d\n", ret); - stm32_usart_tx_dma_terminate(stm32_port); - } - } + /* dma terminate may have been called in case of dma pause failure */ + stm32_usart_tx_dma_pause(stm32_port); + /* Check that TDR is empty before filling FIFO */ ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, @@ -716,13 +747,8 @@ static void stm32_usart_transmit_chars(struct uart_port *port) port->x_char = 0; port->icount.tx++; - if (stm32_usart_tx_dma_started(stm32_port)) { - ret = dmaengine_resume(stm32_port->tx_ch); - if (ret < 0) { - dev_err(port->dev, "DMA failed with error code: %d\n", ret); - stm32_usart_tx_dma_terminate(stm32_port); - } - } + /* dma terminate may have been called in case of dma resume failure */ + stm32_usart_tx_dma_resume(stm32_port); return; } @@ -855,16 +881,11 @@ static void stm32_usart_disable_ms(struct uart_port *port) static void stm32_usart_stop_tx(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); - int ret; stm32_usart_tx_interrupt_disable(port); - if (stm32_usart_tx_dma_started(stm32_port)) { - ret = dmaengine_pause(stm32_port->tx_ch); - if (ret < 0) { - dev_err(port->dev, "DMA failed with error code: %d\n", ret); - stm32_usart_tx_dma_terminate(stm32_port); - } - } + + /* dma terminate may have been called in case of dma pause failure */ + stm32_usart_tx_dma_pause(stm32_port); stm32_usart_rs485_rts_disable(port); } @@ -965,8 +986,22 @@ static int stm32_usart_start_rx_dma_cyclic(struct uart_port *port) struct stm32_port *stm32_port = to_stm32_port(port); const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; struct dma_async_tx_descriptor *desc; + enum dma_status rx_dma_status; int ret; + if (stm32_port->rx_dma_busy) { + rx_dma_status = dmaengine_tx_status(stm32_port->rx_ch, + stm32_port->rx_ch->cookie, + NULL); + if (rx_dma_status == DMA_IN_PROGRESS) + return 0; + + dev_err(port->dev, "DMA failed : status error.\n"); + stm32_usart_rx_dma_terminate(stm32_port); + } + + stm32_port->rx_dma_busy = true; + stm32_port->last_res = RX_BUF_L; /* Prepare a DMA cyclic transaction */ desc = dmaengine_prep_dma_cyclic(stm32_port->rx_ch, @@ -976,6 +1011,7 @@ static int stm32_usart_start_rx_dma_cyclic(struct uart_port *port) DMA_PREP_INTERRUPT); if (!desc) { dev_err(port->dev, "rx dma prep cyclic failed\n"); + stm32_port->rx_dma_busy = false; return -ENODEV; } @@ -986,6 +1022,7 @@ static int stm32_usart_start_rx_dma_cyclic(struct uart_port *port) ret = dma_submit_error(dmaengine_submit(desc)); if (ret) { dmaengine_terminate_sync(stm32_port->rx_ch); + stm32_port->rx_dma_busy = false; return ret; } @@ -1074,7 +1111,7 @@ static void stm32_usart_shutdown(struct uart_port *port) /* Disable RX DMA. */ if (stm32_port->rx_ch) - dmaengine_terminate_async(stm32_port->rx_ch); + stm32_usart_rx_dma_terminate(stm32_port); /* flush RX & TX FIFO */ if (ofs->rqr != UNDEF_REG) @@ -1988,7 +2025,7 @@ static int __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port, stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); /* Poll data from DMA RX buffer if any */ size = stm32_usart_receive_chars(port, true); - dmaengine_terminate_async(stm32_port->rx_ch); + stm32_usart_rx_dma_terminate(stm32_port); uart_unlock_and_check_sysrq_irqrestore(port, flags); if (size) tty_flip_buffer_push(tport); diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index 903285b5aea7..f59f831b2a10 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -199,6 +199,7 @@ struct stm32_port { u32 cr3_irq; /* USART_CR3_RXFTIE */ int last_res; bool tx_dma_busy; /* dma tx transaction in progress */ + bool rx_dma_busy; /* dma rx transaction in progress */ bool throttled; /* port throttled */ bool hw_flow_control; bool swap; /* swap RX & TX pins */ -- cgit v1.2.3 From a01ae50d7eae9e145e595b17fd16a7559e99492b Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Tue, 8 Aug 2023 18:19:05 +0200 Subject: serial: stm32: replace access to DMAR bit by dmaengine_pause/resume It's rather advised to rely on DMA pause / resume instead of clearing/setting DMA request enable bit for the same purpose. Some DMA request/acknowledge race may encountered by doing so. We prefer to use dmaengine_pause and resume instead to pause a dma transfer when it is necessary. Create two new functions (stm32_usart_rx_dma_pause, stm32_usart_rx_dma _resume) to handle dma error when pausing/resuming. And rename stm32_usart_start_rx_dma_cyclic() to stm32_usart_rx_dma_start_or_resume() and use this function to resume an rx dma transfer. If resume fail, stm32_usart_rx_dma_start_or_resume can create a new transfer to continue. It is also safer to close DMA before reset DMAR in stm32_usart_shutdown. Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20230808161906.178996-6-valentin.caron@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 200 +++++++++++++++++++++------------------ 1 file changed, 106 insertions(+), 94 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 0dae05a7abe6..8fc0526be898 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -326,6 +326,22 @@ static int stm32_usart_dma_pause_resume(struct stm32_port *stm32_port, return ret; } +static int stm32_usart_rx_dma_pause(struct stm32_port *stm32_port) +{ + return stm32_usart_dma_pause_resume(stm32_port, stm32_port->rx_ch, + DMA_IN_PROGRESS, dmaengine_pause, + stm32_usart_rx_dma_started, + stm32_usart_rx_dma_terminate); +} + +static int stm32_usart_rx_dma_resume(struct stm32_port *stm32_port) +{ + return stm32_usart_dma_pause_resume(stm32_port, stm32_port->rx_ch, + DMA_PAUSED, dmaengine_resume, + stm32_usart_rx_dma_started, + stm32_usart_rx_dma_terminate); +} + /* Return true when data is pending (in pio mode), and false when no data is pending. */ static bool stm32_usart_pending_rx_pio(struct uart_port *port, u32 *sr) { @@ -485,7 +501,8 @@ static unsigned int stm32_usart_receive_chars(struct uart_port *port, bool force rx_dma_status = dmaengine_tx_status(stm32_port->rx_ch, stm32_port->rx_ch->cookie, &stm32_port->rx_dma_state); - if (rx_dma_status == DMA_IN_PROGRESS) { + if (rx_dma_status == DMA_IN_PROGRESS || + rx_dma_status == DMA_PAUSED) { /* Empty DMA buffer */ size = stm32_usart_receive_chars_dma(port); sr = readl_relaxed(port->membase + ofs->isr); @@ -502,7 +519,6 @@ static unsigned int stm32_usart_receive_chars(struct uart_port *port, bool force } else { /* Disable RX DMA */ stm32_usart_rx_dma_terminate(stm32_port); - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); /* Fall back to interrupt mode */ dev_dbg(port->dev, "DMA error, fallback to irq mode\n"); size = stm32_usart_receive_chars_pio(port); @@ -514,6 +530,76 @@ static unsigned int stm32_usart_receive_chars(struct uart_port *port, bool force return size; } +static void stm32_usart_rx_dma_complete(void *arg) +{ + struct uart_port *port = arg; + struct tty_port *tport = &port->state->port; + unsigned int size; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + size = stm32_usart_receive_chars(port, false); + uart_unlock_and_check_sysrq_irqrestore(port, flags); + if (size) + tty_flip_buffer_push(tport); +} + +static int stm32_usart_rx_dma_start_or_resume(struct uart_port *port) +{ + struct stm32_port *stm32_port = to_stm32_port(port); + struct dma_async_tx_descriptor *desc; + enum dma_status rx_dma_status; + int ret; + + if (stm32_port->throttled) + return 0; + + if (stm32_port->rx_dma_busy) { + rx_dma_status = dmaengine_tx_status(stm32_port->rx_ch, + stm32_port->rx_ch->cookie, + NULL); + if (rx_dma_status == DMA_IN_PROGRESS) + return 0; + + if (rx_dma_status == DMA_PAUSED && !stm32_usart_rx_dma_resume(stm32_port)) + return 0; + + dev_err(port->dev, "DMA failed : status error.\n"); + stm32_usart_rx_dma_terminate(stm32_port); + } + + stm32_port->rx_dma_busy = true; + + stm32_port->last_res = RX_BUF_L; + /* Prepare a DMA cyclic transaction */ + desc = dmaengine_prep_dma_cyclic(stm32_port->rx_ch, + stm32_port->rx_dma_buf, + RX_BUF_L, RX_BUF_P, + DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT); + if (!desc) { + dev_err(port->dev, "rx dma prep cyclic failed\n"); + stm32_port->rx_dma_busy = false; + return -ENODEV; + } + + desc->callback = stm32_usart_rx_dma_complete; + desc->callback_param = port; + + /* Push current DMA transaction in the pending queue */ + ret = dma_submit_error(dmaengine_submit(desc)); + if (ret) { + dmaengine_terminate_sync(stm32_port->rx_ch); + stm32_port->rx_dma_busy = false; + return ret; + } + + /* Issue pending DMA requests */ + dma_async_issue_pending(stm32_port->rx_ch); + + return 0; +} + static void stm32_usart_tx_dma_terminate(struct stm32_port *stm32_port) { dmaengine_terminate_async(stm32_port->tx_ch); @@ -585,20 +671,6 @@ static void stm32_usart_tc_interrupt_enable(struct uart_port *port) stm32_usart_set_bits(port, ofs->cr1, USART_CR1_TCIE); } -static void stm32_usart_rx_dma_complete(void *arg) -{ - struct uart_port *port = arg; - struct tty_port *tport = &port->state->port; - unsigned int size; - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - size = stm32_usart_receive_chars(port, false); - uart_unlock_and_check_sysrq_irqrestore(port, flags); - if (size) - tty_flip_buffer_push(tport); -} - static void stm32_usart_tx_interrupt_disable(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); @@ -924,11 +996,10 @@ static void stm32_usart_throttle(struct uart_port *port) spin_lock_irqsave(&port->lock, flags); /* - * Disable DMA request line if enabled, so the RX data gets queued into the FIFO. + * Pause DMA transfer, so the RX data gets queued into the FIFO. * Hardware flow control is triggered when RX FIFO is full. */ - if (stm32_usart_rx_dma_started(stm32_port)) - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); + stm32_usart_rx_dma_pause(stm32_port); stm32_usart_clr_bits(port, ofs->cr1, stm32_port->cr1_irq); if (stm32_port->cr3_irq) @@ -950,14 +1021,15 @@ static void stm32_usart_unthrottle(struct uart_port *port) if (stm32_port->cr3_irq) stm32_usart_set_bits(port, ofs->cr3, stm32_port->cr3_irq); + stm32_port->throttled = false; + /* - * Switch back to DMA mode (re-enable DMA request line). + * Switch back to DMA mode (resume DMA). * Hardware flow control is stopped when FIFO is not full any more. */ if (stm32_port->rx_ch) - stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR); + stm32_usart_rx_dma_start_or_resume(port); - stm32_port->throttled = false; spin_unlock_irqrestore(&port->lock, flags); } @@ -968,8 +1040,7 @@ static void stm32_usart_stop_rx(struct uart_port *port) const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; /* Disable DMA request line. */ - if (stm32_port->rx_ch) - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); + stm32_usart_rx_dma_pause(stm32_port); stm32_usart_clr_bits(port, ofs->cr1, stm32_port->cr1_irq); if (stm32_port->cr3_irq) @@ -981,64 +1052,6 @@ static void stm32_usart_break_ctl(struct uart_port *port, int break_state) { } -static int stm32_usart_start_rx_dma_cyclic(struct uart_port *port) -{ - struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; - struct dma_async_tx_descriptor *desc; - enum dma_status rx_dma_status; - int ret; - - if (stm32_port->rx_dma_busy) { - rx_dma_status = dmaengine_tx_status(stm32_port->rx_ch, - stm32_port->rx_ch->cookie, - NULL); - if (rx_dma_status == DMA_IN_PROGRESS) - return 0; - - dev_err(port->dev, "DMA failed : status error.\n"); - stm32_usart_rx_dma_terminate(stm32_port); - } - - stm32_port->rx_dma_busy = true; - - stm32_port->last_res = RX_BUF_L; - /* Prepare a DMA cyclic transaction */ - desc = dmaengine_prep_dma_cyclic(stm32_port->rx_ch, - stm32_port->rx_dma_buf, - RX_BUF_L, RX_BUF_P, - DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT); - if (!desc) { - dev_err(port->dev, "rx dma prep cyclic failed\n"); - stm32_port->rx_dma_busy = false; - return -ENODEV; - } - - desc->callback = stm32_usart_rx_dma_complete; - desc->callback_param = port; - - /* Push current DMA transaction in the pending queue */ - ret = dma_submit_error(dmaengine_submit(desc)); - if (ret) { - dmaengine_terminate_sync(stm32_port->rx_ch); - stm32_port->rx_dma_busy = false; - return ret; - } - - /* Issue pending DMA requests */ - dma_async_issue_pending(stm32_port->rx_ch); - - /* - * DMA request line not re-enabled at resume when port is throttled. - * It will be re-enabled by unthrottle ops. - */ - if (!stm32_port->throttled) - stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR); - - return 0; -} - static int stm32_usart_startup(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); @@ -1064,7 +1077,7 @@ static int stm32_usart_startup(struct uart_port *port) writel_relaxed(USART_RQR_RXFRQ, port->membase + ofs->rqr); if (stm32_port->rx_ch) { - ret = stm32_usart_start_rx_dma_cyclic(port); + ret = stm32_usart_rx_dma_start_or_resume(port); if (ret) { free_irq(port->irq, port); return ret; @@ -1811,11 +1824,6 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) pm_runtime_put_noidle(&pdev->dev); stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_PEIE); - cr3 = readl_relaxed(port->membase + ofs->cr3); - cr3 &= ~USART_CR3_EIE; - cr3 &= ~USART_CR3_DMAR; - cr3 &= ~USART_CR3_DDRE; - writel_relaxed(cr3, port->membase + ofs->cr3); if (stm32_port->tx_ch) { stm32_usart_of_dma_tx_remove(stm32_port, pdev); @@ -1827,7 +1835,12 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) dma_release_channel(stm32_port->rx_ch); } - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); + cr3 = readl_relaxed(port->membase + ofs->cr3); + cr3 &= ~USART_CR3_EIE; + cr3 &= ~USART_CR3_DMAR; + cr3 &= ~USART_CR3_DMAT; + cr3 &= ~USART_CR3_DDRE; + writel_relaxed(cr3, port->membase + ofs->cr3); if (stm32_port->wakeup_src) { dev_pm_clear_wake_irq(&pdev->dev); @@ -1999,7 +2012,7 @@ static int __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port, const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; struct tty_port *tport = &port->state->port; int ret; - unsigned int size; + unsigned int size = 0; unsigned long flags; if (!stm32_port->wakeup_src || !tty_port_initialized(tport)) @@ -2021,10 +2034,9 @@ static int __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port, */ if (stm32_port->rx_ch) { spin_lock_irqsave(&port->lock, flags); - /* Avoid race with RX IRQ when DMAR is cleared */ - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); /* Poll data from DMA RX buffer if any */ - size = stm32_usart_receive_chars(port, true); + if (!stm32_usart_rx_dma_pause(stm32_port)) + size += stm32_usart_receive_chars(port, true); stm32_usart_rx_dma_terminate(stm32_port); uart_unlock_and_check_sysrq_irqrestore(port, flags); if (size) @@ -2035,7 +2047,7 @@ static int __maybe_unused stm32_usart_serial_en_wakeup(struct uart_port *port, stm32_usart_receive_chars(port, false); } else { if (stm32_port->rx_ch) { - ret = stm32_usart_start_rx_dma_cyclic(port); + ret = stm32_usart_rx_dma_start_or_resume(port); if (ret) return ret; } -- cgit v1.2.3 From 2490a0ca5735714bd2ba8ba8a41fa9343b422113 Mon Sep 17 00:00:00 2001 From: Amelie Delaunay Date: Tue, 8 Aug 2023 18:19:06 +0200 Subject: serial: stm32: synchronize RX DMA channel in shutdown In shutdown, RX DMA channel is terminated. If the DMA RX callback is scheduled but not yet executed, while a new RX DMA transfer is started, the callback can be executed, and then disturb the ongoing RX DMA transfer. To avoid such a case, call dmaengine_synchronize in shutdown, after the DMA RX channel is terminated. Signed-off-by: Amelie Delaunay Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20230808161906.178996-7-valentin.caron@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 8fc0526be898..5e9cf0c48813 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1123,8 +1123,10 @@ static void stm32_usart_shutdown(struct uart_port *port) dev_err(port->dev, "Transmission is not complete\n"); /* Disable RX DMA. */ - if (stm32_port->rx_ch) + if (stm32_port->rx_ch) { stm32_usart_rx_dma_terminate(stm32_port); + dmaengine_synchronize(stm32_port->rx_ch); + } /* flush RX & TX FIFO */ if (ofs->rqr != UNDEF_REG) -- cgit v1.2.3 From 153fece7b77b0ec4236e4d70430b7474c0cd9299 Mon Sep 17 00:00:00 2001 From: Lucas Tanure Date: Mon, 14 Aug 2023 09:01:27 +0100 Subject: dt-bindings: serial: amlogic,meson-uart: Add compatible string for T7 Amlogic T7 SoCs uses the same UART controller as S4 SoCs and G12A. There is no need for an extra compatible line in the driver, but add T7 compatible line for documentation. Signed-off-by: Lucas Tanure Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230814080128.143613-1-tanure@linux.com Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml index f1ae8c4934d9..2e189e548327 100644 --- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml +++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml @@ -52,6 +52,10 @@ properties: items: - const: amlogic,meson-g12a-uart - const: amlogic,meson-gx-uart + - description: UART controller on S4 compatible SoCs + items: + - const: amlogic,t7-uart + - const: amlogic,meson-s4-uart reg: maxItems: 1 -- cgit v1.2.3 From 6a4197f9763325043abf7690a21124a9facbf52e Mon Sep 17 00:00:00 2001 From: Lucas Tanure Date: Mon, 14 Aug 2023 09:01:28 +0100 Subject: tty: serial: meson: Add a earlycon for the T7 SoC The new Amlogic T7 SoC does not have a always-on uart, so add OF_EARLYCON_DECLARE for it. Signed-off-by: Lucas Tanure Acked-by: Neil Armstrong Link: https://lore.kernel.org/r/20230814080128.143613-2-tanure@linux.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 790d910dafa5..c4f61d82fb72 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -648,6 +648,8 @@ meson_serial_early_console_setup(struct earlycon_device *device, const char *opt OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", meson_serial_early_console_setup); +OF_EARLYCON_DECLARE(meson, "amlogic,t7-uart", + meson_serial_early_console_setup); #define MESON_SERIAL_CONSOLE_PTR(_devname) (&meson_serial_console_##_devname) #else -- cgit v1.2.3 From 8a6498f2b94333f1793bc912b11830655f975470 Mon Sep 17 00:00:00 2001 From: Nick Hu Date: Tue, 15 Aug 2023 17:02:16 +0800 Subject: serial: sifive: Add suspend and resume operations If the Sifive Uart is not used as the wake up source, suspend the uart before the system enter the suspend state to prevent it woken up by unexpected uart interrupt. Resume the uart once the system woken up. Signed-off-by: Nick Hu Reviewed-by: Ben Dooks Link: https://lore.kernel.org/r/20230815090216.2575971-1-nick.hu@sifive.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sifive.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index e2efc3f84eff..d195c5de52e7 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -1019,6 +1019,23 @@ static int sifive_serial_remove(struct platform_device *dev) return 0; } +static int sifive_serial_suspend(struct device *dev) +{ + struct sifive_serial_port *ssp = dev_get_drvdata(dev); + + return uart_suspend_port(&sifive_serial_uart_driver, &ssp->port); +} + +static int sifive_serial_resume(struct device *dev) +{ + struct sifive_serial_port *ssp = dev_get_drvdata(dev); + + return uart_resume_port(&sifive_serial_uart_driver, &ssp->port); +} + +DEFINE_SIMPLE_DEV_PM_OPS(sifive_uart_pm_ops, sifive_serial_suspend, + sifive_serial_resume); + static const struct of_device_id sifive_serial_of_match[] = { { .compatible = "sifive,fu540-c000-uart0" }, { .compatible = "sifive,uart0" }, @@ -1031,6 +1048,7 @@ static struct platform_driver sifive_serial_platform_driver = { .remove = sifive_serial_remove, .driver = { .name = SIFIVE_SERIAL_NAME, + .pm = pm_sleep_ptr(&sifive_uart_pm_ops), .of_match_table = sifive_serial_of_match, }, }; -- cgit v1.2.3 From 5abd01145d0cc6cd1b7c2fe6ee0b9ea0fa13671e Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Thu, 17 Aug 2023 18:54:06 +0800 Subject: serial: tegra: handle clk prepare error in tegra_uart_hw_init() In tegra_uart_hw_init(), the return value of clk_prepare_enable() should be checked since it might fail. Fixes: e9ea096dd225 ("serial: tegra: add serial driver") Signed-off-by: Yi Yang Link: https://lore.kernel.org/r/20230817105406.228674-1-yiyang13@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial-tegra.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 0b597b282fce..d4ec943cb8e9 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -996,7 +996,11 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup) tup->ier_shadow = 0; tup->current_baud = 0; - clk_prepare_enable(tup->uart_clk); + ret = clk_prepare_enable(tup->uart_clk); + if (ret) { + dev_err(tup->uport.dev, "could not enable clk\n"); + return ret; + } /* Reset the UART controller to clear all previous status.*/ reset_control_assert(tup->rst); -- cgit v1.2.3 From e9f0dff15a96add74e8367bd1bca3085180ce80b Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Sun, 6 Aug 2023 17:20:55 +0800 Subject: dt-bindings: serial: snps-dw-apb-uart: make interrupt optional The driver fall back to poll style when there's no irq. "poll" still looks better than no support. Signed-off-by: Jisheng Zhang Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20230806092056.2467-2-jszhang@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml index 3862411c77b5..17c553123f96 100644 --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml @@ -117,7 +117,6 @@ properties: required: - compatible - reg - - interrupts unevaluatedProperties: false -- cgit v1.2.3 From 22130dae0533c474e4e0db930a88caa9b397d083 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Sun, 6 Aug 2023 17:20:56 +0800 Subject: serial: 8250_dw: fall back to poll if there's no interrupt When there's no irq(this can be due to various reasons, for example, no irq from HW support, or we just want to use poll solution, and so on), falling back to poll is still better than no support at all. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20230806092056.2467-3-jszhang@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 7db51781289e..f4cafca1a7da 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -523,7 +523,10 @@ static int dw8250_probe(struct platform_device *pdev) if (!regs) return dev_err_probe(dev, -EINVAL, "no registers defined\n"); - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); + /* no interrupt -> fall back to polling */ + if (irq == -ENXIO) + irq = 0; if (irq < 0) return irq; -- cgit v1.2.3 From 2861ed4d6e6d1a2c9de9bf5b0abd996c2dc673d0 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 7 Aug 2023 17:45:51 -0400 Subject: serial: sc16is7xx: fix broken port 0 uart init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sc16is7xx_config_rs485() function is called only for the second port (index 1, channel B), causing initialization problems for the first port. For the sc16is7xx driver, port->membase and port->mapbase are not set, and their default values are 0. And we set port->iobase to the device index. This means that when the first device is registered using the uart_add_one_port() function, the following values will be in the port structure: port->membase = 0 port->mapbase = 0 port->iobase = 0 Therefore, the function uart_configure_port() in serial_core.c will exit early because of the following check: /* * If there isn't a port here, don't do anything further. */ if (!port->iobase && !port->mapbase && !port->membase) return; Typically, I2C and SPI drivers do not set port->membase and port->mapbase. The max310x driver sets port->membase to ~0 (all ones). By implementing the same change in this driver, uart_configure_port() is now correctly executed for all ports. Fixes: dfeae619d781 ("serial: sc16is7xx") Cc: stable@vger.kernel.org Signed-off-by: Hugo Villeneuve Reviewed-by: Ilpo Järvinen Reviewed-by: Lech Perczak Tested-by: Lech Perczak Link: https://lore.kernel.org/r/20230807214556.540627-2-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 18a48ce052c2..ffe817309413 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1438,6 +1438,12 @@ static int sc16is7xx_probe(struct device *dev, s->p[i].port.fifosize = SC16IS7XX_FIFO_SIZE; s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; s->p[i].port.iobase = i; + /* + * Use all ones as membase to make sure uart_configure_port() in + * serial_core.c does not abort for SPI/I2C devices where the + * membase address is not applicable. + */ + s->p[i].port.membase = (void __iomem *)~0; s->p[i].port.iotype = UPIO_PORT; s->p[i].port.uartclk = freq; s->p[i].port.rs485_config = sc16is7xx_config_rs485; -- cgit v1.2.3 From dabc54a45711fe77674a6c0348231e00e66bd567 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 7 Aug 2023 17:45:52 -0400 Subject: serial: sc16is7xx: remove obsolete out_thread label Commit c8f71b49ee4d ("serial: sc16is7xx: setup GPIO controller later in probe") moved GPIO setup code later in probe function. Doing so also required to move ports cleanup code (out_ports label) after the GPIO cleanup code. After these moves, the out_thread label becomes misplaced and makes part of the cleanup code illogical. This patch remove the now obsolete out_thread label and make GPIO setup code jump to out_ports label if it fails. Signed-off-by: Hugo Villeneuve Reviewed-by: Lech Perczak Tested-by: Lech Perczak Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230807214556.540627-3-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index ffe817309413..93b4137daa8b 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1522,7 +1522,7 @@ static int sc16is7xx_probe(struct device *dev, s->gpio.can_sleep = 1; ret = gpiochip_add_data(&s->gpio, s); if (ret) - goto out_thread; + goto out_ports; } #endif @@ -1548,8 +1548,6 @@ static int sc16is7xx_probe(struct device *dev, #ifdef CONFIG_GPIOLIB if (devtype->nr_gpio) gpiochip_remove(&s->gpio); - -out_thread: #endif out_ports: -- cgit v1.2.3 From 4cf478dc5d707e56aefa258c049872eff054a353 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 7 Aug 2023 17:45:53 -0400 Subject: dt-bindings: sc16is7xx: Add property to change GPIO function Some variants in this series of UART controllers have GPIO pins that are shared between GPIO and modem control lines. The pin mux mode (GPIO or modem control lines) can be set for each ports (channels) supported by the variant. This adds a property to the device tree to set the GPIO pin mux to modem control lines on selected ports if needed. Cc: stable@vger.kernel.org # 6.1.x Signed-off-by: Hugo Villeneuve Acked-by: Conor Dooley Reviewed-by: Lech Perczak Acked-by: Rob Herring Link: https://lore.kernel.org/r/20230807214556.540627-4-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/nxp,sc16is7xx.txt | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt index 0fa8e3e43bf8..1a7e4bff0456 100644 --- a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt +++ b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt @@ -23,6 +23,9 @@ Optional properties: 1 = active low. - irda-mode-ports: An array that lists the indices of the port that should operate in IrDA mode. +- nxp,modem-control-line-ports: An array that lists the indices of the port that + should have shared GPIO lines configured as + modem control lines. Example: sc16is750: sc16is750@51 { @@ -35,6 +38,26 @@ Example: #gpio-cells = <2>; }; + sc16is752: sc16is752@53 { + compatible = "nxp,sc16is752"; + reg = <0x53>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ + gpio-controller; /* Port 0 as GPIOs */ + #gpio-cells = <2>; + }; + + sc16is752: sc16is752@54 { + compatible = "nxp,sc16is752"; + reg = <0x54>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ + }; + * spi as bus Required properties: @@ -59,6 +82,9 @@ Optional properties: 1 = active low. - irda-mode-ports: An array that lists the indices of the port that should operate in IrDA mode. +- nxp,modem-control-line-ports: An array that lists the indices of the port that + should have shared GPIO lines configured as + modem control lines. Example: sc16is750: sc16is750@0 { @@ -70,3 +96,23 @@ Example: gpio-controller; #gpio-cells = <2>; }; + + sc16is752: sc16is752@1 { + compatible = "nxp,sc16is752"; + reg = <1>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ + gpio-controller; /* Port 0 as GPIOs */ + #gpio-cells = <2>; + }; + + sc16is752: sc16is752@2 { + compatible = "nxp,sc16is752"; + reg = <2>; + clocks = <&clk20m>; + interrupt-parent = <&gpio3>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ + }; -- cgit v1.2.3 From 0499942928341d572a42199580433c2b0725211e Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 7 Aug 2023 17:45:54 -0400 Subject: serial: sc16is7xx: fix regression with GPIO configuration Commit 679875d1d880 ("sc16is7xx: Separate GPIOs from modem control lines") and commit 21144bab4f11 ("sc16is7xx: Handle modem status lines") changed the function of the GPIOs pins to act as modem control lines without any possibility of selecting GPIO function. As a consequence, applications that depends on GPIO lines configured by default as GPIO pins no longer work as expected. Also, the change to select modem control lines function was done only for channel A of dual UART variants (752/762). This was not documented in the log message. Allow to specify GPIO or modem control line function in the device tree, and for each of the ports (A or B). Do so by using the new device-tree property named "nxp,modem-control-line-ports" (property added in separate patch). When registering GPIO chip controller, mask-out GPIO pins declared as modem control lines according to this new DT property. Fixes: 679875d1d880 ("sc16is7xx: Separate GPIOs from modem control lines") Fixes: 21144bab4f11 ("sc16is7xx: Handle modem status lines") Cc: stable@vger.kernel.org Signed-off-by: Hugo Villeneuve Reviewed-by: Andy Shevchenko Reviewed-by: Lech Perczak Tested-by: Lech Perczak Acked-by: Rob Herring Link: https://lore.kernel.org/r/20230807214556.540627-5-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 143 +++++++++++++++++++++++++++++++---------- 1 file changed, 108 insertions(+), 35 deletions(-) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 93b4137daa8b..b45e34e3910d 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -236,7 +236,8 @@ /* IOControl register bits (Only 750/760) */ #define SC16IS7XX_IOCONTROL_LATCH_BIT (1 << 0) /* Enable input latching */ -#define SC16IS7XX_IOCONTROL_MODEM_BIT (1 << 1) /* Enable GPIO[7:4] as modem pins */ +#define SC16IS7XX_IOCONTROL_MODEM_A_BIT (1 << 1) /* Enable GPIO[7:4] as modem A pins */ +#define SC16IS7XX_IOCONTROL_MODEM_B_BIT (1 << 2) /* Enable GPIO[3:0] as modem B pins */ #define SC16IS7XX_IOCONTROL_SRESET_BIT (1 << 3) /* Software Reset */ /* EFCR register bits */ @@ -301,12 +302,12 @@ /* Misc definitions */ #define SC16IS7XX_FIFO_SIZE (64) #define SC16IS7XX_REG_SHIFT 2 +#define SC16IS7XX_GPIOS_PER_BANK 4 struct sc16is7xx_devtype { char name[10]; int nr_gpio; int nr_uart; - int has_mctrl; }; #define SC16IS7XX_RECONF_MD (1 << 0) @@ -336,7 +337,9 @@ struct sc16is7xx_port { struct clk *clk; #ifdef CONFIG_GPIOLIB struct gpio_chip gpio; + unsigned long gpio_valid_mask; #endif + u8 mctrl_mask; unsigned char buf[SC16IS7XX_FIFO_SIZE]; struct kthread_worker kworker; struct task_struct *kworker_task; @@ -447,35 +450,30 @@ static const struct sc16is7xx_devtype sc16is74x_devtype = { .name = "SC16IS74X", .nr_gpio = 0, .nr_uart = 1, - .has_mctrl = 0, }; static const struct sc16is7xx_devtype sc16is750_devtype = { .name = "SC16IS750", - .nr_gpio = 4, + .nr_gpio = 8, .nr_uart = 1, - .has_mctrl = 1, }; static const struct sc16is7xx_devtype sc16is752_devtype = { .name = "SC16IS752", - .nr_gpio = 0, + .nr_gpio = 8, .nr_uart = 2, - .has_mctrl = 1, }; static const struct sc16is7xx_devtype sc16is760_devtype = { .name = "SC16IS760", - .nr_gpio = 4, + .nr_gpio = 8, .nr_uart = 1, - .has_mctrl = 1, }; static const struct sc16is7xx_devtype sc16is762_devtype = { .name = "SC16IS762", - .nr_gpio = 0, + .nr_gpio = 8, .nr_uart = 2, - .has_mctrl = 1, }; static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg) @@ -1350,8 +1348,98 @@ static int sc16is7xx_gpio_direction_output(struct gpio_chip *chip, return 0; } + +static int sc16is7xx_gpio_init_valid_mask(struct gpio_chip *chip, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct sc16is7xx_port *s = gpiochip_get_data(chip); + + *valid_mask = s->gpio_valid_mask; + + return 0; +} + +static int sc16is7xx_setup_gpio_chip(struct sc16is7xx_port *s) +{ + struct device *dev = s->p[0].port.dev; + + if (!s->devtype->nr_gpio) + return 0; + + switch (s->mctrl_mask) { + case 0: + s->gpio_valid_mask = GENMASK(7, 0); + break; + case SC16IS7XX_IOCONTROL_MODEM_A_BIT: + s->gpio_valid_mask = GENMASK(3, 0); + break; + case SC16IS7XX_IOCONTROL_MODEM_B_BIT: + s->gpio_valid_mask = GENMASK(7, 4); + break; + default: + break; + } + + if (s->gpio_valid_mask == 0) + return 0; + + s->gpio.owner = THIS_MODULE; + s->gpio.parent = dev; + s->gpio.label = dev_name(dev); + s->gpio.init_valid_mask = sc16is7xx_gpio_init_valid_mask; + s->gpio.direction_input = sc16is7xx_gpio_direction_input; + s->gpio.get = sc16is7xx_gpio_get; + s->gpio.direction_output = sc16is7xx_gpio_direction_output; + s->gpio.set = sc16is7xx_gpio_set; + s->gpio.base = -1; + s->gpio.ngpio = s->devtype->nr_gpio; + s->gpio.can_sleep = 1; + + return gpiochip_add_data(&s->gpio, s); +} #endif +/* + * Configure ports designated to operate as modem control lines. + */ +static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s) +{ + int i; + int ret; + int count; + u32 mctrl_port[2]; + struct device *dev = s->p[0].port.dev; + + count = device_property_count_u32(dev, "nxp,modem-control-line-ports"); + if (count < 0 || count > ARRAY_SIZE(mctrl_port)) + return 0; + + ret = device_property_read_u32_array(dev, "nxp,modem-control-line-ports", + mctrl_port, count); + if (ret) + return ret; + + s->mctrl_mask = 0; + + for (i = 0; i < count; i++) { + /* Use GPIO lines as modem control lines */ + if (mctrl_port[i] == 0) + s->mctrl_mask |= SC16IS7XX_IOCONTROL_MODEM_A_BIT; + else if (mctrl_port[i] == 1) + s->mctrl_mask |= SC16IS7XX_IOCONTROL_MODEM_B_BIT; + } + + if (s->mctrl_mask) + regmap_update_bits( + s->regmap, + SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT, + SC16IS7XX_IOCONTROL_MODEM_A_BIT | + SC16IS7XX_IOCONTROL_MODEM_B_BIT, s->mctrl_mask); + + return 0; +} + static const struct serial_rs485 sc16is7xx_rs485_supported = { .flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, .delay_rts_before_send = 1, @@ -1464,12 +1552,6 @@ static int sc16is7xx_probe(struct device *dev, SC16IS7XX_EFCR_RXDISABLE_BIT | SC16IS7XX_EFCR_TXDISABLE_BIT); - /* Use GPIO lines as modem status registers */ - if (devtype->has_mctrl) - sc16is7xx_port_write(&s->p[i].port, - SC16IS7XX_IOCONTROL_REG, - SC16IS7XX_IOCONTROL_MODEM_BIT); - /* Initialize kthread work structs */ kthread_init_work(&s->p[i].tx_work, sc16is7xx_tx_proc); kthread_init_work(&s->p[i].reg_work, sc16is7xx_reg_proc); @@ -1507,23 +1589,14 @@ static int sc16is7xx_probe(struct device *dev, s->p[u].irda_mode = true; } + ret = sc16is7xx_setup_mctrl_ports(s); + if (ret) + goto out_ports; + #ifdef CONFIG_GPIOLIB - if (devtype->nr_gpio) { - /* Setup GPIO cotroller */ - s->gpio.owner = THIS_MODULE; - s->gpio.parent = dev; - s->gpio.label = dev_name(dev); - s->gpio.direction_input = sc16is7xx_gpio_direction_input; - s->gpio.get = sc16is7xx_gpio_get; - s->gpio.direction_output = sc16is7xx_gpio_direction_output; - s->gpio.set = sc16is7xx_gpio_set; - s->gpio.base = -1; - s->gpio.ngpio = devtype->nr_gpio; - s->gpio.can_sleep = 1; - ret = gpiochip_add_data(&s->gpio, s); - if (ret) - goto out_ports; - } + ret = sc16is7xx_setup_gpio_chip(s); + if (ret) + goto out_ports; #endif /* @@ -1546,7 +1619,7 @@ static int sc16is7xx_probe(struct device *dev, return 0; #ifdef CONFIG_GPIOLIB - if (devtype->nr_gpio) + if (s->gpio_valid_mask) gpiochip_remove(&s->gpio); #endif @@ -1570,7 +1643,7 @@ static void sc16is7xx_remove(struct device *dev) int i; #ifdef CONFIG_GPIOLIB - if (s->devtype->nr_gpio) + if (s->gpio_valid_mask) gpiochip_remove(&s->gpio); #endif -- cgit v1.2.3 From 9baeea723c0fb9c3ba9a336369f758ed9bc6831d Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 7 Aug 2023 17:45:55 -0400 Subject: serial: sc16is7xx: fix bug when first setting GPIO direction When configuring a pin as an output pin with a value of logic 0, we end up as having a value of logic 1 on the output pin. Setting a logic 0 a second time (or more) after that will correctly output a logic 0 on the output pin. By default, all GPIO pins are configured as inputs. When we enter sc16is7xx_gpio_direction_output() for the first time, we first set the desired value in IOSTATE, and then we configure the pin as an output. The datasheet states that writing to IOSTATE register will trigger a transfer of the value to the I/O pin configured as output, so if the pin is configured as an input, nothing will be transferred. Therefore, set the direction first in IODIR, and then set the desired value in IOSTATE. This is what is done in NXP application note AN10587. Fixes: dfeae619d781 ("serial: sc16is7xx") Cc: stable@vger.kernel.org Signed-off-by: Hugo Villeneuve Reviewed-by: Lech Perczak Tested-by: Lech Perczak Link: https://lore.kernel.org/r/20230807214556.540627-6-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index b45e34e3910d..cfc88959b2f7 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1342,9 +1342,18 @@ static int sc16is7xx_gpio_direction_output(struct gpio_chip *chip, state |= BIT(offset); else state &= ~BIT(offset); - sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state); + + /* + * If we write IOSTATE first, and then IODIR, the output value is not + * transferred to the corresponding I/O pin. + * The datasheet states that each register bit will be transferred to + * the corresponding I/O pin programmed as output when writing to + * IOSTATE. Therefore, configure direction first with IODIR, and then + * set value after with IOSTATE. + */ sc16is7xx_port_update(port, SC16IS7XX_IODIR_REG, BIT(offset), BIT(offset)); + sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state); return 0; } -- cgit v1.2.3 From b4a778303ea0fcabcaff974721477a5743e1f8ec Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Mon, 7 Aug 2023 17:45:56 -0400 Subject: serial: sc16is7xx: add missing support for rs485 devicetree properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retrieve rs485 devicetree properties on registration of sc16is7xx ports in case they are attached to an rs485 transceiver. Signed-off-by: Hugo Villeneuve Reviewed-by: Ilpo Järvinen Reviewed-by: Lech Perczak Tested-by: Lech Perczak Link: https://lore.kernel.org/r/20230807214556.540627-7-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index cfc88959b2f7..f61d98e09dc3 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1554,6 +1554,10 @@ static int sc16is7xx_probe(struct device *dev, goto out_ports; } + ret = uart_get_rs485_mode(&s->p[i].port); + if (ret) + goto out_ports; + /* Disable all interrupts */ sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_IER_REG, 0); /* Disable TX/RX */ -- cgit v1.2.3 From 42a569cd0d774fd575395a84481f87a1aaa530df Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Mon, 21 Aug 2023 11:52:51 -0700 Subject: serial: 8250_bcm7271: improve bcm7271 8250 port The 8250 BCM7271 UART is not a direct match to PORT_16550A and other generic ports do not match its hardware capabilities. PORT_ALTR matches the rx trigger levels, but its vendor configurations are not compatible. Unfortunately this means we need to create another port to fully capture the hardware capabilities of the BCM7271 UART. To alleviate some latency pressures, we default the rx trigger level to 8. Signed-off-by: Justin Chen Reviewed-by: Florian Fainelli Acked-by: Doug Berger Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/1692643978-16570-1-git-send-email-justin.chen@broadcom.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_bcm7271.c | 4 +--- drivers/tty/serial/8250/8250_port.c | 8 ++++++++ include/uapi/linux/serial_core.h | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index d4b05d7ad9e8..aa5aff046756 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -1042,7 +1042,7 @@ static int brcmuart_probe(struct platform_device *pdev) dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not "); memset(&up, 0, sizeof(up)); - up.port.type = PORT_16550A; + up.port.type = PORT_BCM7271; up.port.uartclk = clk_rate; up.port.dev = dev; up.port.mapbase = mapbase; @@ -1056,8 +1056,6 @@ static int brcmuart_probe(struct platform_device *pdev) | UPF_FIXED_PORT | UPF_FIXED_TYPE; up.port.dev = dev; up.port.private_data = priv; - up.capabilities = UART_CAP_FIFO | UART_CAP_AFE; - up.port.fifosize = 32; /* Check for a fixed line number */ ret = of_alias_get_id(np, "serial"); diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index f59328e1c35d..fb891b67968f 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -322,6 +322,14 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {2, 66, 130, 194}, .flags = UART_CAP_FIFO, }, + [PORT_BCM7271] = { + .name = "Broadcom BCM7271 UART", + .fifo_size = 32, + .tx_loadsz = 32, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01, + .rxtrig_bytes = {1, 8, 16, 30}, + .flags = UART_CAP_FIFO | UART_CAP_AFE, + }, }; /* Uart divisor latch read */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index d19dabd2c20d..add349889d0a 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -123,6 +123,9 @@ /* Xilinx uartlite */ #define PORT_UARTLITE 74 +/* Broadcom BCM7271 UART */ +#define PORT_BCM7271 76 + /* Broadcom SB1250, etc. SOC */ #define PORT_SB1250_DUART 77 -- cgit v1.2.3 From e327fdc262345ca37b358a51ff0c0046ab1b8d15 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 14 Aug 2023 08:02:09 +0200 Subject: Documentation: devices.txt: Remove ttyIOC* IOC4 serial driver was removed, remove associated devices from documentation. Fixes: a017ef17cfd8 ("tty/serial: remove the ioc4_serial driver") Cc: Christoph Hellwig Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/b5deb1222eb92017f0efe5b5cae127ac11983b3d.1691992627.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/devices.txt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index b1b57f638b94..75a408f72402 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -2692,14 +2692,8 @@ 46 = /dev/ttyCPM0 PPC CPM (SCC or SMC) - port 0 ... 49 = /dev/ttyCPM5 PPC CPM (SCC or SMC) - port 3 - 50 = /dev/ttyIOC0 Altix serial card - ... - 81 = /dev/ttyIOC31 Altix serial card 82 = /dev/ttyVR0 NEC VR4100 series SIU 83 = /dev/ttyVR1 NEC VR4100 series DSIU - 84 = /dev/ttyIOC84 Altix ioc4 serial card - ... - 115 = /dev/ttyIOC115 Altix ioc4 serial card 116 = /dev/ttySIOC0 Altix ioc3 serial card ... 147 = /dev/ttySIOC31 Altix ioc3 serial card @@ -2762,9 +2756,6 @@ 46 = /dev/cucpm0 Callout device for ttyCPM0 ... 49 = /dev/cucpm5 Callout device for ttyCPM5 - 50 = /dev/cuioc40 Callout device for ttyIOC40 - ... - 81 = /dev/cuioc431 Callout device for ttyIOC431 82 = /dev/cuvr0 Callout device for ttyVR0 83 = /dev/cuvr1 Callout device for ttyVR1 -- cgit v1.2.3 From 27681960f05515555441d7bf58d565cbc68137f3 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 14 Aug 2023 08:02:10 +0200 Subject: Documentation: devices.txt: Remove ttySIOC* IOC3 serial driver was removed, remove associated devices from documentation. Fixes: 9c860e4cf708 ("tty/serial: remove the ioc3_serial driver") Cc: Christoph Hellwig Signed-off-by: Christophe Leroy Link: https://lore.kernel.org/r/f13b5c64f8cb6d8f2357d7be14397676b27ac2a2.1691992627.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/devices.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index 75a408f72402..1ba5b7c4973c 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -2694,9 +2694,6 @@ 49 = /dev/ttyCPM5 PPC CPM (SCC or SMC) - port 3 82 = /dev/ttyVR0 NEC VR4100 series SIU 83 = /dev/ttyVR1 NEC VR4100 series DSIU - 116 = /dev/ttySIOC0 Altix ioc3 serial card - ... - 147 = /dev/ttySIOC31 Altix ioc3 serial card 148 = /dev/ttyPSC0 PPC PSC - port 0 ... 153 = /dev/ttyPSC5 PPC PSC - port 5 -- cgit v1.2.3 From 4b91dcc2f601cc2098b5fead71344704ddcff8b7 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 14 Aug 2023 08:02:11 +0200 Subject: Documentation: devices.txt: Fix minors for ttyCPM* ttyCPM* devices belong to CPM_UART driver at the first place and that driver provides 6 ports. Fixes: e29c3f81eb89 ("Documentation: devices.txt: reconcile serial/ucc_uart minor numers") Cc: Randy Dunlap Signed-off-by: Christophe Leroy Reviewed-by: Randy Dunlap Link: https://lore.kernel.org/r/27d7124cf86157e2a27c2b039e769041994d3f22.1691992627.git.christophe.leroy@csgroup.eu Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/devices.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index 1ba5b7c4973c..839054923530 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -2691,7 +2691,7 @@ 45 = /dev/ttyMM1 Marvell MPSC - port 1 (obsolete unused) 46 = /dev/ttyCPM0 PPC CPM (SCC or SMC) - port 0 ... - 49 = /dev/ttyCPM5 PPC CPM (SCC or SMC) - port 3 + 51 = /dev/ttyCPM5 PPC CPM (SCC or SMC) - port 5 82 = /dev/ttyVR0 NEC VR4100 series SIU 83 = /dev/ttyVR1 NEC VR4100 series DSIU 148 = /dev/ttyPSC0 PPC PSC - port 0 @@ -2752,7 +2752,7 @@ 43 = /dev/ttycusmx2 Callout device for ttySMX2 46 = /dev/cucpm0 Callout device for ttyCPM0 ... - 49 = /dev/cucpm5 Callout device for ttyCPM5 + 51 = /dev/cucpm5 Callout device for ttyCPM5 82 = /dev/cuvr0 Callout device for ttyVR0 83 = /dev/cuvr1 Callout device for ttyVR1 -- cgit v1.2.3 From db726a2f3b4bc0cbf8e6cfd529d2d8eabb587d70 Mon Sep 17 00:00:00 2001 From: Lucas Tanure Date: Sun, 27 Aug 2023 09:29:44 +0100 Subject: Revert "tty: serial: meson: Add a earlycon for the T7 SoC" This reverts commit 6a4197f9763325043abf7690a21124a9facbf52e New SoC will use ttyS0 instead of ttyAML, so T7 SoC doesn't need a OF_EARLYCON_DECLARE. Fixes: 6a4197f97633 ("tty: serial: meson: Add a earlycon for the T7 SoC") Signed-off-by: Lucas Tanure Link: https://lore.kernel.org/r/20230827082944.5100-1-tanure@linux.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index c4f61d82fb72..790d910dafa5 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -648,8 +648,6 @@ meson_serial_early_console_setup(struct earlycon_device *device, const char *opt OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", meson_serial_early_console_setup); -OF_EARLYCON_DECLARE(meson, "amlogic,t7-uart", - meson_serial_early_console_setup); #define MESON_SERIAL_CONSOLE_PTR(_devname) (&meson_serial_console_##_devname) #else -- cgit v1.2.3 From 0d029ab8a05b5a21af9425c02816f5d6de054b7e Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:34 +0200 Subject: tty: n_tty: make flow of n_tty_receive_buf_common() a bool The 'flow' parameter of n_tty_receive_buf_common() is meant to be a boolean value. So use bool and alter call sites accordingly. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index f44f38bb412e..8b2bacb3e40d 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1665,7 +1665,7 @@ static void __receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp, */ static size_t n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const u8 *fp, - int count, int flow) + int count, bool flow) { struct n_tty_data *ldata = tty->disc_data; size_t rcvd = 0; @@ -1748,13 +1748,13 @@ n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const u8 *fp, static void n_tty_receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp, size_t count) { - n_tty_receive_buf_common(tty, cp, fp, count, 0); + n_tty_receive_buf_common(tty, cp, fp, count, false); } static size_t n_tty_receive_buf2(struct tty_struct *tty, const u8 *cp, const u8 *fp, size_t count) { - return n_tty_receive_buf_common(tty, cp, fp, count, 1); + return n_tty_receive_buf_common(tty, cp, fp, count, true); } /** -- cgit v1.2.3 From d414034ec901c3821f17bd44b8eaaa5820253417 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:35 +0200 Subject: tty: n_tty: use output character directly There is no point to use a local variable to store the character when we can pass it directly. This assignment comes from era when we used to do get_user(c, b). We no longer need this, so fix this. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 8b2bacb3e40d..f6fa4dbdf78f 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2373,8 +2373,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, nr -= num; if (nr == 0) break; - c = *b; - if (process_output(c, tty) < 0) + if (process_output(*b, tty) < 0) break; b++; nr--; } -- cgit v1.2.3 From 68d90d5f7b68652287fbcbcfe245c2c8b667d021 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:36 +0200 Subject: tty: n_tty: use 'num' for writes' counts We have a separate misnomer 'c' to hold the retuned value from tty->ops->write(). Instead, use 'num' already defined on another place (and already properly typed). Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-4-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index f6fa4dbdf78f..7f9fee4cf7cf 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2335,8 +2335,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, { const u8 *b = buf; DEFINE_WAIT_FUNC(wait, woken_wake_function); - int c; - ssize_t retval = 0; + ssize_t num, retval = 0; /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */ if (L_TOSTOP(tty) && file->f_op->write_iter != redirected_tty_write) { @@ -2362,7 +2361,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, } if (O_OPOST(tty)) { while (nr > 0) { - ssize_t num = process_output_block(tty, b, nr); + num = process_output_block(tty, b, nr); if (num < 0) { if (num == -EAGAIN) break; @@ -2384,16 +2383,16 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, while (nr > 0) { mutex_lock(&ldata->output_lock); - c = tty->ops->write(tty, b, nr); + num = tty->ops->write(tty, b, nr); mutex_unlock(&ldata->output_lock); - if (c < 0) { - retval = c; + if (num < 0) { + retval = num; goto break_out; } - if (!c) + if (!num) break; - b += c; - nr -= c; + b += num; + nr -= num; } } if (!nr) -- cgit v1.2.3 From 73276e3a1097ff58d9d167fc9a593cc249d1fd6f Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:37 +0200 Subject: tty: n_tty: use time_is_before_jiffies() in n_tty_receive_overrun() The jiffies tests in n_tty_receive_overrun() are simplified ratelimiting (without locking). We could use struct ratelimit_state and the helpers, but to me, it occurs to be too complex for this use case. But the code currently tests both if the time passed (the first time_after()) and if jiffies wrapped around (the second time_after()). time_is_before_jiffies() takes care of both, provided overrun_time is initialized at the allocation time. So switch to time_is_before_jiffies(), the same what ratelimiting does. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-5-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 7f9fee4cf7cf..c0b23e975877 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1173,8 +1173,7 @@ static void n_tty_receive_overrun(const struct tty_struct *tty) struct n_tty_data *ldata = tty->disc_data; ldata->num_overrun++; - if (time_after(jiffies, ldata->overrun_time + HZ) || - time_after(ldata->overrun_time, jiffies)) { + if (time_is_before_jiffies(ldata->overrun_time + HZ)) { tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun); ldata->overrun_time = jiffies; ldata->num_overrun = 0; -- cgit v1.2.3 From c3b2b26f6eaad5d48fe6dd2d9bada07b193bdb61 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:38 +0200 Subject: tty: n_tty: make n_tty_data::num_overrun unsigned n_tty_data::num_overrun is unlikely to overflow in a second. But make it explicitly unsigned to avoid printing negative values. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-6-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index c0b23e975877..7f8f6cfa8843 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -99,7 +99,7 @@ struct n_tty_data { /* private to n_tty_receive_overrun (single-threaded) */ unsigned long overrun_time; - int num_overrun; + unsigned int num_overrun; /* non-atomic */ bool no_room; @@ -1174,7 +1174,7 @@ static void n_tty_receive_overrun(const struct tty_struct *tty) ldata->num_overrun++; if (time_is_before_jiffies(ldata->overrun_time + HZ)) { - tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun); + tty_warn(tty, "%u input overrun(s)\n", ldata->num_overrun); ldata->overrun_time = jiffies; ldata->num_overrun = 0; } -- cgit v1.2.3 From 819287f0f335cf74d6486eb7f3d465b9668bc9d8 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:39 +0200 Subject: tty: n_tty: use MASK() for masking out size bits In n_tty, there is already a macro to mask out top bits from ring buffer counters. It is MASK() added some time ago. So use it more in the code to make it more readable. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-7-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 7f8f6cfa8843..07b6a013b5ab 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -138,23 +138,23 @@ static inline size_t read_cnt(struct n_tty_data *ldata) static inline unsigned char read_buf(struct n_tty_data *ldata, size_t i) { - return ldata->read_buf[i & (N_TTY_BUF_SIZE - 1)]; + return ldata->read_buf[MASK(i)]; } static inline unsigned char *read_buf_addr(struct n_tty_data *ldata, size_t i) { - return &ldata->read_buf[i & (N_TTY_BUF_SIZE - 1)]; + return &ldata->read_buf[MASK(i)]; } static inline unsigned char echo_buf(struct n_tty_data *ldata, size_t i) { smp_rmb(); /* Matches smp_wmb() in add_echo_byte(). */ - return ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)]; + return ldata->echo_buf[MASK(i)]; } static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i) { - return &ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)]; + return &ldata->echo_buf[MASK(i)]; } /* If we are not echoing the data, perhaps this is a secret so erase it */ @@ -1359,7 +1359,7 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c, put_tty_queue(c, ldata); handle_newline: - set_bit(ldata->read_head & (N_TTY_BUF_SIZE - 1), ldata->read_flags); + set_bit(MASK(ldata->read_head), ldata->read_flags); put_tty_queue(c, ldata); smp_store_release(&ldata->canon_head, ldata->read_head); kill_fasync(&tty->fasync, SIGIO, POLL_IN); @@ -1505,14 +1505,14 @@ n_tty_receive_buf_real_raw(const struct tty_struct *tty, const u8 *cp, struct n_tty_data *ldata = tty->disc_data; size_t n, head; - head = ldata->read_head & (N_TTY_BUF_SIZE - 1); + head = MASK(ldata->read_head); n = min_t(size_t, count, N_TTY_BUF_SIZE - head); memcpy(read_buf_addr(ldata, head), cp, n); ldata->read_head += n; cp += n; count -= n; - head = ldata->read_head & (N_TTY_BUF_SIZE - 1); + head = MASK(ldata->read_head); n = min_t(size_t, count, N_TTY_BUF_SIZE - head); memcpy(read_buf_addr(ldata, head), cp, n); ldata->read_head += n; @@ -1779,8 +1779,7 @@ static void n_tty_set_termios(struct tty_struct *tty, const struct ktermios *old ldata->canon_head = ldata->read_tail; ldata->push = 0; } else { - set_bit((ldata->read_head - 1) & (N_TTY_BUF_SIZE - 1), - ldata->read_flags); + set_bit(MASK(ldata->read_head - 1), ldata->read_flags); ldata->canon_head = ldata->read_head; ldata->push = 1; } @@ -1941,7 +1940,7 @@ static bool copy_from_read_buf(const struct tty_struct *tty, size_t n; bool is_eof; size_t head = smp_load_acquire(&ldata->commit_head); - size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); + size_t tail = MASK(ldata->read_tail); n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail); n = min(*nr, n); @@ -2004,7 +2003,7 @@ static bool canon_copy_from_read_buf(const struct tty_struct *tty, canon_head = smp_load_acquire(&ldata->canon_head); n = min(*nr, canon_head - ldata->read_tail); - tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); + tail = MASK(ldata->read_tail); size = min_t(size_t, tail + n, N_TTY_BUF_SIZE); n_tty_trace("%s: nr:%zu tail:%zu n:%zu size:%zu\n", @@ -2466,7 +2465,7 @@ static unsigned long inq_canon(struct n_tty_data *ldata) nr = head - tail; /* Skip EOF-chars.. */ while (MASK(head) != MASK(tail)) { - if (test_bit(tail & (N_TTY_BUF_SIZE - 1), ldata->read_flags) && + if (test_bit(MASK(tail), ldata->read_flags) && read_buf(ldata, tail) == __DISABLED_CHAR) nr--; tail++; -- cgit v1.2.3 From 102dc8aac8d04be7ec6ee030962f7a40dc6d9731 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:40 +0200 Subject: tty: n_tty: move canon handling to a separate function n_tty_receive_char_special() is already complicated enough. Split the canon handling to a separate function: n_tty_receive_char_canon(). Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-8-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 158 +++++++++++++++++++++++++++++----------------------- 1 file changed, 87 insertions(+), 71 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 07b6a013b5ab..0149dc9dd0b1 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1262,6 +1262,91 @@ static bool n_tty_receive_char_flow_ctrl(struct tty_struct *tty, unsigned char c return true; } +static bool n_tty_receive_char_canon(struct tty_struct *tty, u8 c) +{ + struct n_tty_data *ldata = tty->disc_data; + + if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || + (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { + eraser(c, tty); + commit_echoes(tty); + + return true; + } + + if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { + ldata->lnext = 1; + if (L_ECHO(tty)) { + finish_erasing(ldata); + if (L_ECHOCTL(tty)) { + echo_char_raw('^', ldata); + echo_char_raw('\b', ldata); + commit_echoes(tty); + } + } + + return true; + } + + if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && L_IEXTEN(tty)) { + size_t tail = ldata->canon_head; + + finish_erasing(ldata); + echo_char(c, tty); + echo_char_raw('\n', ldata); + while (MASK(tail) != MASK(ldata->read_head)) { + echo_char(read_buf(ldata, tail), tty); + tail++; + } + commit_echoes(tty); + + return true; + } + + if (c == '\n') { + if (L_ECHO(tty) || L_ECHONL(tty)) { + echo_char_raw('\n', ldata); + commit_echoes(tty); + } + goto handle_newline; + } + + if (c == EOF_CHAR(tty)) { + c = __DISABLED_CHAR; + goto handle_newline; + } + + if ((c == EOL_CHAR(tty)) || + (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { + /* + * XXX are EOL_CHAR and EOL2_CHAR echoed?!? + */ + if (L_ECHO(tty)) { + /* Record the column of first canon char. */ + if (ldata->canon_head == ldata->read_head) + echo_set_canon_col(ldata); + echo_char(c, tty); + commit_echoes(tty); + } + /* + * XXX does PARMRK doubling happen for + * EOL_CHAR and EOL2_CHAR? + */ + if (c == (unsigned char) '\377' && I_PARMRK(tty)) + put_tty_queue(c, ldata); + +handle_newline: + set_bit(MASK(ldata->read_head), ldata->read_flags); + put_tty_queue(c, ldata); + smp_store_release(&ldata->canon_head, ldata->read_head); + kill_fasync(&tty->fasync, SIGIO, POLL_IN); + wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM); + return true; + } + + return false; +} + static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c, bool lookahead_done) { @@ -1296,77 +1381,8 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c, } else if (c == '\n' && I_INLCR(tty)) c = '\r'; - if (ldata->icanon) { - if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || - (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { - eraser(c, tty); - commit_echoes(tty); - return; - } - if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { - ldata->lnext = 1; - if (L_ECHO(tty)) { - finish_erasing(ldata); - if (L_ECHOCTL(tty)) { - echo_char_raw('^', ldata); - echo_char_raw('\b', ldata); - commit_echoes(tty); - } - } - return; - } - if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && L_IEXTEN(tty)) { - size_t tail = ldata->canon_head; - - finish_erasing(ldata); - echo_char(c, tty); - echo_char_raw('\n', ldata); - while (MASK(tail) != MASK(ldata->read_head)) { - echo_char(read_buf(ldata, tail), tty); - tail++; - } - commit_echoes(tty); - return; - } - if (c == '\n') { - if (L_ECHO(tty) || L_ECHONL(tty)) { - echo_char_raw('\n', ldata); - commit_echoes(tty); - } - goto handle_newline; - } - if (c == EOF_CHAR(tty)) { - c = __DISABLED_CHAR; - goto handle_newline; - } - if ((c == EOL_CHAR(tty)) || - (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { - /* - * XXX are EOL_CHAR and EOL2_CHAR echoed?!? - */ - if (L_ECHO(tty)) { - /* Record the column of first canon char. */ - if (ldata->canon_head == ldata->read_head) - echo_set_canon_col(ldata); - echo_char(c, tty); - commit_echoes(tty); - } - /* - * XXX does PARMRK doubling happen for - * EOL_CHAR and EOL2_CHAR? - */ - if (c == (unsigned char) '\377' && I_PARMRK(tty)) - put_tty_queue(c, ldata); - -handle_newline: - set_bit(MASK(ldata->read_head), ldata->read_flags); - put_tty_queue(c, ldata); - smp_store_release(&ldata->canon_head, ldata->read_head); - kill_fasync(&tty->fasync, SIGIO, POLL_IN); - wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM); - return; - } - } + if (ldata->icanon && n_tty_receive_char_canon(tty, c)) + return; if (L_ECHO(tty)) { finish_erasing(ldata); -- cgit v1.2.3 From 008304079da79ab8dd122fe9e581494d10c0a3cc Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:41 +0200 Subject: tty: n_tty: move newline handling to a separate function Currently, n_tty handles the newline in a label in n_tty_receive_char_canon(). That is invoked from two more places. Split this code to a separate function and avoid the label in this case. This makes the code flow more understandable. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-9-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0149dc9dd0b1..632516d7b487 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1262,6 +1262,17 @@ static bool n_tty_receive_char_flow_ctrl(struct tty_struct *tty, unsigned char c return true; } +static void n_tty_receive_handle_newline(struct tty_struct *tty, u8 c) +{ + struct n_tty_data *ldata = tty->disc_data; + + set_bit(MASK(ldata->read_head), ldata->read_flags); + put_tty_queue(c, ldata); + smp_store_release(&ldata->canon_head, ldata->read_head); + kill_fasync(&tty->fasync, SIGIO, POLL_IN); + wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM); +} + static bool n_tty_receive_char_canon(struct tty_struct *tty, u8 c) { struct n_tty_data *ldata = tty->disc_data; @@ -1308,12 +1319,16 @@ static bool n_tty_receive_char_canon(struct tty_struct *tty, u8 c) echo_char_raw('\n', ldata); commit_echoes(tty); } - goto handle_newline; + n_tty_receive_handle_newline(tty, c); + + return true; } if (c == EOF_CHAR(tty)) { c = __DISABLED_CHAR; - goto handle_newline; + n_tty_receive_handle_newline(tty, c); + + return true; } if ((c == EOL_CHAR(tty)) || @@ -1335,12 +1350,8 @@ static bool n_tty_receive_char_canon(struct tty_struct *tty, u8 c) if (c == (unsigned char) '\377' && I_PARMRK(tty)) put_tty_queue(c, ldata); -handle_newline: - set_bit(MASK(ldata->read_head), ldata->read_flags); - put_tty_queue(c, ldata); - smp_store_release(&ldata->canon_head, ldata->read_head); - kill_fasync(&tty->fasync, SIGIO, POLL_IN); - wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM); + n_tty_receive_handle_newline(tty, c); + return true; } -- cgit v1.2.3 From 046b44ab0f5a87ba5788606155c5a6761169616a Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:42 +0200 Subject: tty: n_tty: remove unsigned char casts from character constants We compile with -funsigned-char, so all character constants are already unsigned chars. Therefore, remove superfluous casts. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-10-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 632516d7b487..369f5dd9cc4b 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1347,7 +1347,7 @@ static bool n_tty_receive_char_canon(struct tty_struct *tty, u8 c) * XXX does PARMRK doubling happen for * EOL_CHAR and EOL2_CHAR? */ - if (c == (unsigned char) '\377' && I_PARMRK(tty)) + if (c == '\377' && I_PARMRK(tty)) put_tty_queue(c, ldata); n_tty_receive_handle_newline(tty, c); @@ -1409,7 +1409,7 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c, } /* PARMRK doubling check */ - if (c == (unsigned char) '\377' && I_PARMRK(tty)) + if (c == '\377' && I_PARMRK(tty)) put_tty_queue(c, ldata); put_tty_queue(c, ldata); @@ -1444,7 +1444,7 @@ static void n_tty_receive_char(struct tty_struct *tty, unsigned char c) commit_echoes(tty); } /* PARMRK doubling check */ - if (c == (unsigned char) '\377' && I_PARMRK(tty)) + if (c == '\377' && I_PARMRK(tty)) put_tty_queue(c, ldata); put_tty_queue(c, ldata); } -- cgit v1.2.3 From d88c3c2675f9d41c15297fa001e79812f4dcc9dd Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:43 +0200 Subject: tty: n_tty: simplify chars_in_buffer() The 'if' in chars_in_buffer() is misleadingly inverted. And since the only difference is the head used for computation, cache the head using ternary operator. And use that in return directly. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-11-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 369f5dd9cc4b..e722065b2db4 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -219,13 +219,9 @@ static void n_tty_kick_worker(const struct tty_struct *tty) static ssize_t chars_in_buffer(const struct tty_struct *tty) { const struct n_tty_data *ldata = tty->disc_data; - ssize_t n = 0; + size_t head = ldata->icanon ? ldata->canon_head : ldata->commit_head; - if (!ldata->icanon) - n = ldata->commit_head - ldata->read_tail; - else - n = ldata->canon_head - ldata->read_tail; - return n; + return head - ldata->read_tail; } /** -- cgit v1.2.3 From b9b96b2089e9563a77a69e0fcfbedc5285ce890c Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:44 +0200 Subject: tty: n_tty: use u8 for chars and flags Unify with the tty layer and use u8 for both chars and flags. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-12-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 72 ++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index e722065b2db4..cf42b8b4ad2e 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -109,9 +109,9 @@ struct n_tty_data { unsigned char push:1; /* shared by producer and consumer */ - char read_buf[N_TTY_BUF_SIZE]; + u8 read_buf[N_TTY_BUF_SIZE]; DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE); - unsigned char echo_buf[N_TTY_BUF_SIZE]; + u8 echo_buf[N_TTY_BUF_SIZE]; /* consumer-published */ size_t read_tail; @@ -136,23 +136,23 @@ static inline size_t read_cnt(struct n_tty_data *ldata) return ldata->read_head - ldata->read_tail; } -static inline unsigned char read_buf(struct n_tty_data *ldata, size_t i) +static inline u8 read_buf(struct n_tty_data *ldata, size_t i) { return ldata->read_buf[MASK(i)]; } -static inline unsigned char *read_buf_addr(struct n_tty_data *ldata, size_t i) +static inline u8 *read_buf_addr(struct n_tty_data *ldata, size_t i) { return &ldata->read_buf[MASK(i)]; } -static inline unsigned char echo_buf(struct n_tty_data *ldata, size_t i) +static inline u8 echo_buf(struct n_tty_data *ldata, size_t i) { smp_rmb(); /* Matches smp_wmb() in add_echo_byte(). */ return ldata->echo_buf[MASK(i)]; } -static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i) +static inline u8 *echo_buf_addr(struct n_tty_data *ldata, size_t i) { return &ldata->echo_buf[MASK(i)]; } @@ -303,7 +303,7 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) * * n_tty_receive_buf()/producer path: * caller holds non-exclusive %termios_rwsem */ -static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata) +static inline void put_tty_queue(u8 c, struct n_tty_data *ldata) { *read_buf_addr(ldata, ldata->read_head) = c; ldata->read_head++; @@ -377,7 +377,7 @@ static void n_tty_flush_buffer(struct tty_struct *tty) * character. We use this to correctly compute the on-screen size of the * character when printing. */ -static inline int is_utf8_continuation(unsigned char c) +static inline int is_utf8_continuation(u8 c) { return (c & 0xc0) == 0x80; } @@ -390,7 +390,7 @@ static inline int is_utf8_continuation(unsigned char c) * Returns: true if the utf8 character @c is a multibyte continuation character * and the terminal is in unicode mode. */ -static inline int is_continuation(unsigned char c, const struct tty_struct *tty) +static inline int is_continuation(u8 c, const struct tty_struct *tty) { return I_IUTF8(tty) && is_utf8_continuation(c); } @@ -414,7 +414,7 @@ static inline int is_continuation(unsigned char c, const struct tty_struct *tty) * Locking: should be called under the %output_lock to protect the column state * and space left in the buffer. */ -static int do_output_char(unsigned char c, struct tty_struct *tty, int space) +static int do_output_char(u8 c, struct tty_struct *tty, int space) { struct n_tty_data *ldata = tty->disc_data; int spaces; @@ -488,7 +488,7 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) * Locking: %output_lock to protect column state and space left (also, this is *called from n_tty_write() under the tty layer write lock). */ -static int process_output(unsigned char c, struct tty_struct *tty) +static int process_output(u8 c, struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; int space, retval; @@ -524,12 +524,12 @@ static int process_output(unsigned char c, struct tty_struct *tty) * called from n_tty_write() under the tty layer write lock). */ static ssize_t process_output_block(struct tty_struct *tty, - const unsigned char *buf, unsigned int nr) + const u8 *buf, unsigned int nr) { struct n_tty_data *ldata = tty->disc_data; int space; int i; - const unsigned char *cp; + const u8 *cp; mutex_lock(&ldata->output_lock); @@ -542,7 +542,7 @@ static ssize_t process_output_block(struct tty_struct *tty, nr = space; for (i = 0, cp = buf; i < nr; i++, cp++) { - unsigned char c = *cp; + u8 c = *cp; switch (c) { case '\n': @@ -609,7 +609,7 @@ static size_t __process_echoes(struct tty_struct *tty) struct n_tty_data *ldata = tty->disc_data; int space, old_space; size_t tail; - unsigned char c; + u8 c; old_space = space = tty_write_room(tty); @@ -617,7 +617,7 @@ static size_t __process_echoes(struct tty_struct *tty) while (MASK(ldata->echo_commit) != MASK(tail)) { c = echo_buf(ldata, tail); if (c == ECHO_OP_START) { - unsigned char op; + u8 op; bool space_left = true; /* @@ -818,7 +818,7 @@ static void flush_echoes(struct tty_struct *tty) * * Add a character or operation byte to the echo buffer. */ -static inline void add_echo_byte(unsigned char c, struct n_tty_data *ldata) +static inline void add_echo_byte(u8 c, struct n_tty_data *ldata) { *echo_buf_addr(ldata, ldata->echo_head) = c; smp_wmb(); /* Matches smp_rmb() in echo_buf(). */ @@ -889,7 +889,7 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab, * * This variant does not treat control characters specially. */ -static void echo_char_raw(unsigned char c, struct n_tty_data *ldata) +static void echo_char_raw(u8 c, struct n_tty_data *ldata) { if (c == ECHO_OP_START) { add_echo_byte(ECHO_OP_START, ldata); @@ -910,7 +910,7 @@ static void echo_char_raw(unsigned char c, struct n_tty_data *ldata) * This variant tags control characters to be echoed as "^X" (where X is the * letter representing the control char). */ -static void echo_char(unsigned char c, const struct tty_struct *tty) +static void echo_char(u8 c, const struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; @@ -948,7 +948,7 @@ static inline void finish_erasing(struct n_tty_data *ldata) * Locking: n_tty_receive_buf()/producer path: * caller holds non-exclusive %termios_rwsem */ -static void eraser(unsigned char c, const struct tty_struct *tty) +static void eraser(u8 c, const struct tty_struct *tty) { struct n_tty_data *ldata = tty->disc_data; enum { ERASE, WERASE, KILL } kill_type; @@ -1188,7 +1188,7 @@ static void n_tty_receive_overrun(const struct tty_struct *tty) * caller holds non-exclusive %termios_rwsem */ static void n_tty_receive_parity_error(const struct tty_struct *tty, - unsigned char c) + u8 c) { struct n_tty_data *ldata = tty->disc_data; @@ -1206,7 +1206,7 @@ static void n_tty_receive_parity_error(const struct tty_struct *tty, } static void -n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) +n_tty_receive_signal_char(struct tty_struct *tty, int signal, u8 c) { isig(signal, tty); if (I_IXON(tty)) @@ -1218,7 +1218,7 @@ n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) process_echoes(tty); } -static bool n_tty_is_char_flow_ctrl(struct tty_struct *tty, unsigned char c) +static bool n_tty_is_char_flow_ctrl(struct tty_struct *tty, u8 c) { return c == START_CHAR(tty) || c == STOP_CHAR(tty); } @@ -1238,7 +1238,7 @@ static bool n_tty_is_char_flow_ctrl(struct tty_struct *tty, unsigned char c) * Returns true if @c is consumed as flow-control character, the character * must not be treated as normal character. */ -static bool n_tty_receive_char_flow_ctrl(struct tty_struct *tty, unsigned char c, +static bool n_tty_receive_char_flow_ctrl(struct tty_struct *tty, u8 c, bool lookahead_done) { if (!n_tty_is_char_flow_ctrl(tty, c)) @@ -1354,7 +1354,7 @@ static bool n_tty_receive_char_canon(struct tty_struct *tty, u8 c) return false; } -static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c, +static void n_tty_receive_char_special(struct tty_struct *tty, u8 c, bool lookahead_done) { struct n_tty_data *ldata = tty->disc_data; @@ -1423,7 +1423,7 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c, * caller holds non-exclusive %termios_rwsem * publishes canon_head if canonical mode is active */ -static void n_tty_receive_char(struct tty_struct *tty, unsigned char c) +static void n_tty_receive_char(struct tty_struct *tty, u8 c) { struct n_tty_data *ldata = tty->disc_data; @@ -1445,7 +1445,7 @@ static void n_tty_receive_char(struct tty_struct *tty, unsigned char c) put_tty_queue(c, ldata); } -static void n_tty_receive_char_closing(struct tty_struct *tty, unsigned char c, +static void n_tty_receive_char_closing(struct tty_struct *tty, u8 c, bool lookahead_done) { if (I_ISTRIP(tty)) @@ -1465,7 +1465,7 @@ static void n_tty_receive_char_closing(struct tty_struct *tty, unsigned char c, } static void -n_tty_receive_char_flagged(struct tty_struct *tty, unsigned char c, char flag) +n_tty_receive_char_flagged(struct tty_struct *tty, u8 c, u8 flag) { switch (flag) { case TTY_BREAK: @@ -1479,13 +1479,13 @@ n_tty_receive_char_flagged(struct tty_struct *tty, unsigned char c, char flag) n_tty_receive_overrun(tty); break; default: - tty_err(tty, "unknown flag %d\n", flag); + tty_err(tty, "unknown flag %u\n", flag); break; } } static void -n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag) +n_tty_receive_char_lnext(struct tty_struct *tty, u8 c, u8 flag) { struct n_tty_data *ldata = tty->disc_data; @@ -1505,7 +1505,7 @@ static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const u8 *cp, const u8 *fp, size_t count) { struct n_tty_data *ldata = tty->disc_data; - unsigned char flag = TTY_NORMAL; + u8 flag = TTY_NORMAL; ldata->lookahead_count += count; @@ -1562,7 +1562,7 @@ static void n_tty_receive_buf_closing(struct tty_struct *tty, const u8 *cp, const u8 *fp, int count, bool lookahead_done) { - char flag = TTY_NORMAL; + u8 flag = TTY_NORMAL; while (count--) { if (fp) @@ -1955,7 +1955,7 @@ static inline int input_available_p(const struct tty_struct *tty, int poll) * read_tail published */ static bool copy_from_read_buf(const struct tty_struct *tty, - unsigned char **kbp, + u8 **kbp, size_t *nr) { @@ -1968,7 +1968,7 @@ static bool copy_from_read_buf(const struct tty_struct *tty, n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail); n = min(*nr, n); if (n) { - unsigned char *from = read_buf_addr(ldata, tail); + u8 *from = read_buf_addr(ldata, tail); memcpy(*kbp, from, n); is_eof = n == 1 && *from == EOF_CHAR(tty); tty_audit_add_data(tty, from, n); @@ -2010,7 +2010,7 @@ static bool copy_from_read_buf(const struct tty_struct *tty, * read_tail published */ static bool canon_copy_from_read_buf(const struct tty_struct *tty, - unsigned char **kbp, + u8 **kbp, size_t *nr) { struct n_tty_data *ldata = tty->disc_data; @@ -2229,7 +2229,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf, while (nr) { /* First test for status change. */ if (packet && tty->link->ctrl.pktstatus) { - unsigned char cs; + u8 cs; if (kb != kbuf) break; spin_lock_irq(&tty->link->ctrl.lock); -- cgit v1.2.3 From e30364c70895c1ba90b28b85a82aa0d98aab8c81 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:45 +0200 Subject: tty: n_tty: unify counts to size_t Some count types are already 'size_t' for a long time. Some were switched to 'size_t' recently. Unify the rest with those now. This allows for some min_t()s to become min()s. And make one min() an explicit min_t() as we are comparing signed 'room' to unsigned 'count'. Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-13-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index cf42b8b4ad2e..bd6cd28f734f 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1523,27 +1523,27 @@ static void n_tty_lookahead_flow_ctrl(struct tty_struct *tty, const u8 *cp, static void n_tty_receive_buf_real_raw(const struct tty_struct *tty, const u8 *cp, - int count) + size_t count) { struct n_tty_data *ldata = tty->disc_data; size_t n, head; head = MASK(ldata->read_head); - n = min_t(size_t, count, N_TTY_BUF_SIZE - head); + n = min(count, N_TTY_BUF_SIZE - head); memcpy(read_buf_addr(ldata, head), cp, n); ldata->read_head += n; cp += n; count -= n; head = MASK(ldata->read_head); - n = min_t(size_t, count, N_TTY_BUF_SIZE - head); + n = min(count, N_TTY_BUF_SIZE - head); memcpy(read_buf_addr(ldata, head), cp, n); ldata->read_head += n; } static void n_tty_receive_buf_raw(struct tty_struct *tty, const u8 *cp, const u8 *fp, - int count) + size_t count) { struct n_tty_data *ldata = tty->disc_data; u8 flag = TTY_NORMAL; @@ -1560,7 +1560,7 @@ n_tty_receive_buf_raw(struct tty_struct *tty, const u8 *cp, const u8 *fp, static void n_tty_receive_buf_closing(struct tty_struct *tty, const u8 *cp, const u8 *fp, - int count, bool lookahead_done) + size_t count, bool lookahead_done) { u8 flag = TTY_NORMAL; @@ -1573,7 +1573,7 @@ n_tty_receive_buf_closing(struct tty_struct *tty, const u8 *cp, const u8 *fp, } static void n_tty_receive_buf_standard(struct tty_struct *tty, const u8 *cp, - const u8 *fp, int count, + const u8 *fp, size_t count, bool lookahead_done) { struct n_tty_data *ldata = tty->disc_data; @@ -1612,11 +1612,11 @@ static void n_tty_receive_buf_standard(struct tty_struct *tty, const u8 *cp, } static void __receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp, - int count) + size_t count) { struct n_tty_data *ldata = tty->disc_data; bool preops = I_ISTRIP(tty) || (I_IUCLC(tty) && L_IEXTEN(tty)); - size_t la_count = min_t(size_t, ldata->lookahead_count, count); + size_t la_count = min(ldata->lookahead_count, count); if (ldata->real_raw) n_tty_receive_buf_real_raw(tty, cp, count); @@ -1687,11 +1687,11 @@ static void __receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp, */ static size_t n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const u8 *fp, - int count, bool flow) + size_t count, bool flow) { struct n_tty_data *ldata = tty->disc_data; - size_t rcvd = 0; - int room, n, overflow; + size_t n, rcvd = 0; + int room, overflow; down_read(&tty->termios_rwsem); @@ -1724,7 +1724,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const u8 *fp, } else overflow = 0; - n = min(count, room); + n = min_t(size_t, count, room); if (!n) break; @@ -1954,9 +1954,8 @@ static inline int input_available_p(const struct tty_struct *tty, int poll) * caller holds non-exclusive %termios_rwsem; * read_tail published */ -static bool copy_from_read_buf(const struct tty_struct *tty, - u8 **kbp, - size_t *nr) +static bool copy_from_read_buf(const struct tty_struct *tty, u8 **kbp, + size_t *nr) { struct n_tty_data *ldata = tty->disc_data; @@ -2009,8 +2008,7 @@ static bool copy_from_read_buf(const struct tty_struct *tty, * caller holds non-exclusive %termios_rwsem; * read_tail published */ -static bool canon_copy_from_read_buf(const struct tty_struct *tty, - u8 **kbp, +static bool canon_copy_from_read_buf(const struct tty_struct *tty, u8 **kbp, size_t *nr) { struct n_tty_data *ldata = tty->disc_data; -- cgit v1.2.3 From 2aa91851ffa7cdfc0a63330d273115d38324b585 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:46 +0200 Subject: tty: n_tty: extract ECHO_OP processing to a separate function __process_echoes() contains ECHO_OPs processing. It is stuffed in a while loop and the whole function is barely readable. Separate it to a new function: n_tty_process_echo_ops(). Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-14-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 194 ++++++++++++++++++++++++++-------------------------- 1 file changed, 98 insertions(+), 96 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index bd6cd28f734f..edf59f6fc669 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -582,6 +582,100 @@ break_out: return i; } +static int n_tty_process_echo_ops(struct tty_struct *tty, size_t *tail, + int space) +{ + struct n_tty_data *ldata = tty->disc_data; + u8 op; + + /* + * Since add_echo_byte() is called without holding output_lock, we + * might see only portion of multi-byte operation. + */ + if (MASK(ldata->echo_commit) == MASK(*tail + 1)) + return -ENODATA; + + /* + * If the buffer byte is the start of a multi-byte operation, get the + * next byte, which is either the op code or a control character value. + */ + op = echo_buf(ldata, *tail + 1); + + switch (op) { + case ECHO_OP_ERASE_TAB: { + unsigned int num_chars, num_bs; + + if (MASK(ldata->echo_commit) == MASK(*tail + 2)) + return -ENODATA; + + num_chars = echo_buf(ldata, *tail + 2); + + /* + * Determine how many columns to go back in order to erase the + * tab. This depends on the number of columns used by other + * characters within the tab area. If this (modulo 8) count is + * from the start of input rather than from a previous tab, we + * offset by canon column. Otherwise, tab spacing is normal. + */ + if (!(num_chars & 0x80)) + num_chars += ldata->canon_column; + num_bs = 8 - (num_chars & 7); + + if (num_bs > space) + return -ENOSPC; + + space -= num_bs; + while (num_bs--) { + tty_put_char(tty, '\b'); + if (ldata->column > 0) + ldata->column--; + } + *tail += 3; + break; + } + case ECHO_OP_SET_CANON_COL: + ldata->canon_column = ldata->column; + *tail += 2; + break; + + case ECHO_OP_MOVE_BACK_COL: + if (ldata->column > 0) + ldata->column--; + *tail += 2; + break; + + case ECHO_OP_START: + /* This is an escaped echo op start code */ + if (!space) + return -ENOSPC; + + tty_put_char(tty, ECHO_OP_START); + ldata->column++; + space--; + *tail += 2; + break; + + default: + /* + * If the op is not a special byte code, it is a ctrl char + * tagged to be echoed as "^X" (where X is the letter + * representing the control char). Note that we must ensure + * there is enough space for the whole ctrl pair. + */ + if (space < 2) + return -ENOSPC; + + tty_put_char(tty, '^'); + tty_put_char(tty, op ^ 0100); + ldata->column += 2; + space -= 2; + *tail += 2; + break; + } + + return space; +} + /** * __process_echoes - write pending echo characters * @tty: terminal device @@ -617,104 +711,12 @@ static size_t __process_echoes(struct tty_struct *tty) while (MASK(ldata->echo_commit) != MASK(tail)) { c = echo_buf(ldata, tail); if (c == ECHO_OP_START) { - u8 op; - bool space_left = true; - - /* - * Since add_echo_byte() is called without holding - * output_lock, we might see only portion of multi-byte - * operation. - */ - if (MASK(ldata->echo_commit) == MASK(tail + 1)) + int ret = n_tty_process_echo_ops(tty, &tail, space); + if (ret == -ENODATA) goto not_yet_stored; - /* - * If the buffer byte is the start of a multi-byte - * operation, get the next byte, which is either the - * op code or a control character value. - */ - op = echo_buf(ldata, tail + 1); - - switch (op) { - case ECHO_OP_ERASE_TAB: { - unsigned int num_chars, num_bs; - - if (MASK(ldata->echo_commit) == MASK(tail + 2)) - goto not_yet_stored; - num_chars = echo_buf(ldata, tail + 2); - - /* - * Determine how many columns to go back - * in order to erase the tab. - * This depends on the number of columns - * used by other characters within the tab - * area. If this (modulo 8) count is from - * the start of input rather than from a - * previous tab, we offset by canon column. - * Otherwise, tab spacing is normal. - */ - if (!(num_chars & 0x80)) - num_chars += ldata->canon_column; - num_bs = 8 - (num_chars & 7); - - if (num_bs > space) { - space_left = false; - break; - } - space -= num_bs; - while (num_bs--) { - tty_put_char(tty, '\b'); - if (ldata->column > 0) - ldata->column--; - } - tail += 3; - break; - } - case ECHO_OP_SET_CANON_COL: - ldata->canon_column = ldata->column; - tail += 2; - break; - - case ECHO_OP_MOVE_BACK_COL: - if (ldata->column > 0) - ldata->column--; - tail += 2; - break; - - case ECHO_OP_START: - /* This is an escaped echo op start code */ - if (!space) { - space_left = false; - break; - } - tty_put_char(tty, ECHO_OP_START); - ldata->column++; - space--; - tail += 2; - break; - - default: - /* - * If the op is not a special byte code, - * it is a ctrl char tagged to be echoed - * as "^X" (where X is the letter - * representing the control char). - * Note that we must ensure there is - * enough space for the whole ctrl pair. - * - */ - if (space < 2) { - space_left = false; - break; - } - tty_put_char(tty, '^'); - tty_put_char(tty, op ^ 0100); - ldata->column += 2; - space -= 2; - tail += 2; - } - - if (!space_left) + if (ret < 0) break; + space = ret; } else { if (O_OPOST(tty)) { int retval = do_output_char(c, tty, space); -- cgit v1.2.3 From a84853c5954fe2c1b97db2f005ae156dc29ae233 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Sun, 27 Aug 2023 09:41:47 +0200 Subject: tty: n_tty: deduplicate copy code in n_tty_receive_buf_real_raw() The code is duplicated to perform the copy twice -- to handle buffer wrap-around. Instead of the duplication, roll this into the loop. (And add some blank lines around to have the code a bit more readable.) Signed-off-by: "Jiri Slaby (SUSE)" Link: https://lore.kernel.org/r/20230827074147.2287-15-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index edf59f6fc669..6c9a408d67cd 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1528,19 +1528,18 @@ n_tty_receive_buf_real_raw(const struct tty_struct *tty, const u8 *cp, size_t count) { struct n_tty_data *ldata = tty->disc_data; - size_t n, head; - - head = MASK(ldata->read_head); - n = min(count, N_TTY_BUF_SIZE - head); - memcpy(read_buf_addr(ldata, head), cp, n); - ldata->read_head += n; - cp += n; - count -= n; - - head = MASK(ldata->read_head); - n = min(count, N_TTY_BUF_SIZE - head); - memcpy(read_buf_addr(ldata, head), cp, n); - ldata->read_head += n; + + /* handle buffer wrap-around by a loop */ + for (unsigned int i = 0; i < 2; i++) { + size_t head = MASK(ldata->read_head); + size_t n = min(count, N_TTY_BUF_SIZE - head); + + memcpy(read_buf_addr(ldata, head), cp, n); + + ldata->read_head += n; + cp += n; + count -= n; + } } static void -- cgit v1.2.3 From ebf05c7dc92c11b0355aaa0e94064beadaa4b05c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 25 Aug 2023 17:28:20 +0200 Subject: tty: shrink the size of struct tty_struct by 40 bytes It's been a long time since anyone has looked at what struct tty_struct looks like in memory, turns out there was a ton of holes. So move things around a bit, change one variable (closing) from being an int to a bool (it is only being tested for 0/1), and we end up saving 40 bytes per structure overall on x86-64 systems. Before this patch: /* size: 696, cachelines: 11, members: 37 */ /* sum members: 665, holes: 8, sum holes: 31 */ /* forced alignments: 2, forced holes: 1, sum forced holes: 4 */ /* last cacheline: 56 bytes */ After this change: /* size: 656, cachelines: 11, members: 37 */ /* sum members: 654, holes: 1, sum holes: 2 */ /* forced alignments: 2 */ /* last cacheline: 16 bytes */ Cc: Jiri Slaby Link: https://lore.kernel.org/r/2023082519-cobbler-unholy-8d1f@gregkh Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/linux/tty.h b/include/linux/tty.h index e8d5d9997aca..f002d0f25db7 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -192,13 +192,14 @@ struct tty_operations; */ struct tty_struct { struct kref kref; + int index; struct device *dev; struct tty_driver *driver; + struct tty_port *port; const struct tty_operations *ops; - int index; - struct ld_semaphore ldisc_sem; struct tty_ldisc *ldisc; + struct ld_semaphore ldisc_sem; struct mutex atomic_write_lock; struct mutex legacy_mutex; @@ -209,6 +210,7 @@ struct tty_struct { char name[64]; unsigned long flags; int count; + unsigned int receive_room; struct winsize winsize; struct { @@ -219,16 +221,16 @@ struct tty_struct { } __aligned(sizeof(unsigned long)) flow; struct { - spinlock_t lock; struct pid *pgrp; struct pid *session; + spinlock_t lock; unsigned char pktstatus; bool packet; unsigned long unused[0]; } __aligned(sizeof(unsigned long)) ctrl; bool hw_stopped; - unsigned int receive_room; + bool closing; int flow_change; struct tty_struct *link; @@ -239,15 +241,13 @@ struct tty_struct { void *disc_data; void *driver_data; spinlock_t files_lock; + int write_cnt; + unsigned char *write_buf; + struct list_head tty_files; #define N_TTY_BUF_SIZE 4096 - - int closing; - unsigned char *write_buf; - int write_cnt; struct work_struct SAK_work; - struct tty_port *port; } __randomize_layout; /* Each of a tty's open files has private_data pointing to tty_file_private */ -- cgit v1.2.3