From 4480c27ca3eaaaae134633a594fba5601da13b4a Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 8 Jun 2022 16:22:55 +0200 Subject: [PATCH 001/401] gfs2: Add glockfd debugfs file When a process has a gfs2 file open, the file is keeping a reference on the underlying gfs2 inode, and the inode is keeping the inode's iopen glock held in shared mode. In other words, the process depends on the iopen glock of each open gfs2 file. Expose those dependencies in a new "glockfd" debugfs file. The new debugfs file contains one line for each gfs2 file descriptor, specifying the tgid, file descriptor number, and glock name, e.g., 1601 6 5/816d This list is compiled by iterating all tasks on the system using find_ge_pid(), and all file descriptors of each task using task_lookup_next_fd_rcu(). To make that work from gfs2, export those two functions. Signed-off-by: Andreas Gruenbacher --- fs/file.c | 1 + fs/gfs2/glock.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ kernel/pid.c | 1 + 3 files changed, 151 insertions(+) diff --git a/fs/file.c b/fs/file.c index 3bcc1ecc314a..5f9c802a5d8d 100644 --- a/fs/file.c +++ b/fs/file.c @@ -980,6 +980,7 @@ struct file *task_lookup_next_fd_rcu(struct task_struct *task, unsigned int *ret *ret_fd = fd; return file; } +EXPORT_SYMBOL(task_lookup_next_fd_rcu); /* * Lightweight file lookup - no refcnt increment if fd table isn't shared. diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index c992d53013d3..85352126e662 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -33,6 +33,9 @@ #include #include #include +#include +#include +#include #include "gfs2.h" #include "incore.h" @@ -2745,6 +2748,149 @@ static const struct file_operations gfs2_glstats_fops = { .release = gfs2_glocks_release, }; +struct gfs2_glockfd_iter { + struct super_block *sb; + unsigned int tgid; + struct task_struct *task; + unsigned int fd; + struct file *file; +}; + +static struct task_struct *gfs2_glockfd_next_task(struct gfs2_glockfd_iter *i) +{ + struct pid_namespace *ns = task_active_pid_ns(current); + struct pid *pid; + + if (i->task) + put_task_struct(i->task); + + rcu_read_lock(); +retry: + i->task = NULL; + pid = find_ge_pid(i->tgid, ns); + if (pid) { + i->tgid = pid_nr_ns(pid, ns); + i->task = pid_task(pid, PIDTYPE_TGID); + if (!i->task) { + i->tgid++; + goto retry; + } + get_task_struct(i->task); + } + rcu_read_unlock(); + return i->task; +} + +static struct file *gfs2_glockfd_next_file(struct gfs2_glockfd_iter *i) +{ + if (i->file) { + fput(i->file); + i->file = NULL; + } + + rcu_read_lock(); + for(;; i->fd++) { + struct inode *inode; + + i->file = task_lookup_next_fd_rcu(i->task, &i->fd); + if (!i->file) { + i->fd = 0; + break; + } + inode = file_inode(i->file); + if (inode->i_sb != i->sb) + continue; + if (get_file_rcu(i->file)) + break; + } + rcu_read_unlock(); + return i->file; +} + +static void *gfs2_glockfd_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct gfs2_glockfd_iter *i = seq->private; + + if (*pos) + return NULL; + while (gfs2_glockfd_next_task(i)) { + if (gfs2_glockfd_next_file(i)) + return i; + i->tgid++; + } + return NULL; +} + +static void *gfs2_glockfd_seq_next(struct seq_file *seq, void *iter_ptr, + loff_t *pos) +{ + struct gfs2_glockfd_iter *i = seq->private; + + (*pos)++; + i->fd++; + do { + if (gfs2_glockfd_next_file(i)) + return i; + i->tgid++; + } while (gfs2_glockfd_next_task(i)); + return NULL; +} + +static void gfs2_glockfd_seq_stop(struct seq_file *seq, void *iter_ptr) +{ + struct gfs2_glockfd_iter *i = seq->private; + + if (i->file) + fput(i->file); + if (i->task) + put_task_struct(i->task); +} + +static int gfs2_glockfd_seq_show(struct seq_file *seq, void *iter_ptr) +{ + struct gfs2_glockfd_iter *i = seq->private; + struct inode *inode = file_inode(i->file); + struct gfs2_glock *gl; + + inode_lock_shared(inode); + gl = GFS2_I(inode)->i_iopen_gh.gh_gl; + if (gl) { + seq_printf(seq, "%d %u %u/%llx\n", + i->tgid, i->fd, gl->gl_name.ln_type, + (unsigned long long)gl->gl_name.ln_number); + } + inode_unlock_shared(inode); + return 0; +} + +static const struct seq_operations gfs2_glockfd_seq_ops = { + .start = gfs2_glockfd_seq_start, + .next = gfs2_glockfd_seq_next, + .stop = gfs2_glockfd_seq_stop, + .show = gfs2_glockfd_seq_show, +}; + +static int gfs2_glockfd_open(struct inode *inode, struct file *file) +{ + struct gfs2_glockfd_iter *i; + struct gfs2_sbd *sdp = inode->i_private; + + i = __seq_open_private(file, &gfs2_glockfd_seq_ops, + sizeof(struct gfs2_glockfd_iter)); + if (!i) + return -ENOMEM; + i->sb = sdp->sd_vfs; + return 0; +} + +static const struct file_operations gfs2_glockfd_fops = { + .owner = THIS_MODULE, + .open = gfs2_glockfd_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; + DEFINE_SEQ_ATTRIBUTE(gfs2_sbstats); void gfs2_create_debugfs_file(struct gfs2_sbd *sdp) @@ -2754,6 +2900,9 @@ void gfs2_create_debugfs_file(struct gfs2_sbd *sdp) debugfs_create_file("glocks", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp, &gfs2_glocks_fops); + debugfs_create_file("glockfd", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp, + &gfs2_glockfd_fops); + debugfs_create_file("glstats", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp, &gfs2_glstats_fops); diff --git a/kernel/pid.c b/kernel/pid.c index 2fc0a16ec77b..3fbc5e46b721 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -519,6 +519,7 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns) { return idr_get_next(&ns->idr, &nr); } +EXPORT_SYMBOL_GPL(find_ge_pid); struct pid *pidfd_get_pid(unsigned int fd, unsigned int *flags) { From 56535dc695f8e215dffb9557d6bcbdf46ff785d2 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Thu, 23 Jun 2022 23:29:36 +0200 Subject: [PATCH 002/401] gfs2: Add flocks to glockfd debugfs file Include flock glocks in the "glockfd" debugfs file. Those are similar to the iopen glocks; while an open file is holding an flock, it is holding the file's flock glock. We cannot take f_fl_mutex in gfs2_glockfd_seq_show_flock() or else dumping the "glockfd" file would block on flock operations. Instead, use the file->f_lock spin lock to protect the f_fl_gh.gh_gl glock pointer. Signed-off-by: Andreas Gruenbacher --- fs/gfs2/file.c | 22 ++++++++++++++++++++-- fs/gfs2/glock.c | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 2cceb193dcd8..25f4080bc973 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -1444,6 +1444,22 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) return dlm_posix_lock(ls->ls_dlm, ip->i_no_addr, file, cmd, fl); } +static void __flock_holder_uninit(struct file *file, struct gfs2_holder *fl_gh) +{ + struct gfs2_glock *gl = fl_gh->gh_gl; + + /* + * Make sure gfs2_glock_put() won't sleep under the file->f_lock + * spinlock. + */ + + gfs2_glock_hold(gl); + spin_lock(&file->f_lock); + gfs2_holder_uninit(fl_gh); + spin_unlock(&file->f_lock); + gfs2_glock_put(gl); +} + static int do_flock(struct file *file, int cmd, struct file_lock *fl) { struct gfs2_file *fp = file->private_data; @@ -1475,7 +1491,9 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) &gfs2_flock_glops, CREATE, &gl); if (error) goto out; + spin_lock(&file->f_lock); gfs2_holder_init(gl, state, flags, fl_gh); + spin_unlock(&file->f_lock); gfs2_glock_put(gl); } for (sleeptime = 1; sleeptime <= 4; sleeptime <<= 1) { @@ -1486,7 +1504,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) msleep(sleeptime); } if (error) { - gfs2_holder_uninit(fl_gh); + __flock_holder_uninit(file, fl_gh); if (error == GLR_TRYFAILED) error = -EAGAIN; } else { @@ -1508,7 +1526,7 @@ static void do_unflock(struct file *file, struct file_lock *fl) locks_lock_file_wait(file, fl); if (gfs2_holder_initialized(fl_gh)) { gfs2_glock_dq(fl_gh); - gfs2_holder_uninit(fl_gh); + __flock_holder_uninit(file, fl_gh); } mutex_unlock(&fp->f_fl_mutex); } diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 85352126e662..533ec772166d 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -2846,6 +2846,28 @@ static void gfs2_glockfd_seq_stop(struct seq_file *seq, void *iter_ptr) put_task_struct(i->task); } +static void gfs2_glockfd_seq_show_flock(struct seq_file *seq, + struct gfs2_glockfd_iter *i) +{ + struct gfs2_file *fp = i->file->private_data; + struct gfs2_holder *fl_gh = &fp->f_fl_gh; + struct lm_lockname gl_name = { .ln_type = LM_TYPE_RESERVED }; + + if (!READ_ONCE(fl_gh->gh_gl)) + return; + + spin_lock(&i->file->f_lock); + if (gfs2_holder_initialized(fl_gh)) + gl_name = fl_gh->gh_gl->gl_name; + spin_unlock(&i->file->f_lock); + + if (gl_name.ln_type != LM_TYPE_RESERVED) { + seq_printf(seq, "%d %u %u/%llx\n", + i->tgid, i->fd, gl_name.ln_type, + (unsigned long long)gl_name.ln_number); + } +} + static int gfs2_glockfd_seq_show(struct seq_file *seq, void *iter_ptr) { struct gfs2_glockfd_iter *i = seq->private; @@ -2859,6 +2881,7 @@ static int gfs2_glockfd_seq_show(struct seq_file *seq, void *iter_ptr) i->tgid, i->fd, gl->gl_name.ln_type, (unsigned long long)gl->gl_name.ln_number); } + gfs2_glockfd_seq_show_flock(seq, i); inode_unlock_shared(inode); return 0; } From cbe6d2576e2cf7571e781439728ad31bdfd9dfcb Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Tue, 5 Apr 2022 22:07:30 +0200 Subject: [PATCH 003/401] gfs2: Add GL_NOPID flag for process-independent glock holders Add a GL_NOPID flag to indicate that once a glock holder has been acquired, it won't be associated with the current process anymore. This is useful for iopen and flock glocks which are associated with open files, as well as journal glock holders and similar which are associated with the filesystem. Once GL_NOPID is used for all applicable glocks (see the next patches), processes will no longer be falsely reported as holding glocks which they are not actually holding in the glocks dump file. Unlike before, when a process is reported as having "(ended)", this will indicate an actual bug. Signed-off-by: Andreas Gruenbacher --- fs/gfs2/glock.c | 41 +++++++++++++++++++++++++++++++---------- fs/gfs2/glock.h | 1 + 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 533ec772166d..f80fba5d1d4d 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1467,6 +1467,15 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) va_end(args); } +static inline bool pid_is_meaningful(const struct gfs2_holder *gh) +{ + if (!(gh->gh_flags & GL_NOPID)) + return true; + if (gh->gh_state == LM_ST_UNLOCKED) + return true; + return false; +} + /** * add_to_queue - Add a holder to the wait queue (but look for recursion) * @gh: the holder structure to add @@ -1503,10 +1512,17 @@ __acquires(&gl->gl_lockref.lock) } list_for_each_entry(gh2, &gl->gl_holders, gh_list) { - if (unlikely(gh2->gh_owner_pid == gh->gh_owner_pid && - (gh->gh_gl->gl_ops->go_type != LM_TYPE_FLOCK) && - !test_bit(HIF_MAY_DEMOTE, &gh2->gh_iflags))) - goto trap_recursive; + if (likely(gh2->gh_owner_pid != gh->gh_owner_pid)) + continue; + if (gh->gh_gl->gl_ops->go_type == LM_TYPE_FLOCK) + continue; + if (test_bit(HIF_MAY_DEMOTE, &gh2->gh_iflags)) + continue; + if (!pid_is_meaningful(gh2)) + continue; + goto trap_recursive; + } + list_for_each_entry(gh2, &gl->gl_holders, gh_list) { if (try_futile && !(gh2->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) { fail: @@ -2321,19 +2337,24 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags) static void dump_holder(struct seq_file *seq, const struct gfs2_holder *gh, const char *fs_id_buf) { - struct task_struct *gh_owner = NULL; + const char *comm = "(none)"; + pid_t owner_pid = 0; char flags_buf[32]; rcu_read_lock(); - if (gh->gh_owner_pid) + if (pid_is_meaningful(gh)) { + struct task_struct *gh_owner; + + comm = "(ended)"; + owner_pid = pid_nr(gh->gh_owner_pid); gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID); + if (gh_owner) + comm = gh_owner->comm; + } gfs2_print_dbg(seq, "%s H: s:%s f:%s e:%d p:%ld [%s] %pS\n", fs_id_buf, state2str(gh->gh_state), hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags), - gh->gh_error, - gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1, - gh_owner ? gh_owner->comm : "(ended)", - (void *)gh->gh_ip); + gh->gh_error, (long)owner_pid, comm, (void *)gh->gh_ip); rcu_read_unlock(); } diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index c0ae9100a0bc..e764ebeba54c 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -91,6 +91,7 @@ enum { #define GL_ASYNC 0x0040 #define GL_EXACT 0x0080 #define GL_SKIP 0x0100 +#define GL_NOPID 0x0200 #define GL_NOCACHE 0x0400 /* From b582d5f05ddbd61bb72896b31ff83d7f0b0862f5 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 6 Apr 2022 12:51:27 +0200 Subject: [PATCH 004/401] gfs2: Mark flock glock holders as GL_NOPID Add the GL_NOPID flag for flock glock holders. Clean up the flag setting code in do_flock. Signed-off-by: Andreas Gruenbacher --- fs/gfs2/file.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 25f4080bc973..1383f9598011 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -1472,7 +1472,9 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) int sleeptime; state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; - flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY_1CB) | GL_EXACT; + flags = GL_EXACT | GL_NOPID; + if (!IS_SETLKW(cmd)) + flags |= LM_FLAG_TRY_1CB; mutex_lock(&fp->f_fl_mutex); @@ -1500,7 +1502,8 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) error = gfs2_glock_nq(fl_gh); if (error != GLR_TRYFAILED) break; - fl_gh->gh_flags = LM_FLAG_TRY | GL_EXACT; + fl_gh->gh_flags &= ~LM_FLAG_TRY_1CB; + fl_gh->gh_flags |= LM_FLAG_TRY; msleep(sleeptime); } if (error) { From ebdc416c9c0bed245d6cda92ae2a98483e513051 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Tue, 5 Apr 2022 22:39:16 +0200 Subject: [PATCH 005/401] gfs2: Mark the remaining process-independent glock holders as GL_NOPID Add the GL_NOPID flag for the remaining glock holders which are not associated with the current process. Signed-off-by: Andreas Gruenbacher --- fs/gfs2/inode.c | 6 ++++-- fs/gfs2/ops_fstype.c | 14 ++++++++------ fs/gfs2/super.c | 3 ++- fs/gfs2/util.c | 6 ++++-- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index c8ec876f33ea..e211ed8636b5 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -143,7 +143,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, if (blktype != GFS2_BLKST_UNLINKED) gfs2_cancel_delete_work(io_gl); - error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, + error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, + GL_EXACT | GL_NOPID, &ip->i_iopen_gh); gfs2_glock_put(io_gl); if (unlikely(error)) @@ -720,7 +721,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, error = insert_inode_locked4(inode, ip->i_no_addr, iget_test, &ip->i_no_addr); BUG_ON(error); - error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); + error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT | GL_NOPID, + &ip->i_iopen_gh); if (error) goto fail_gunlock2; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index c9b423c874a3..904a2d47c4b3 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -403,7 +403,8 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh, error = gfs2_glock_nq_num(sdp, GFS2_MOUNT_LOCK, &gfs2_nondisk_glops, - LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE, + LM_ST_EXCLUSIVE, + LM_FLAG_NOEXP | GL_NOCACHE | GL_NOPID, mount_gh); if (error) { fs_err(sdp, "can't acquire mount glock: %d\n", error); @@ -413,7 +414,7 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh, error = gfs2_glock_nq_num(sdp, GFS2_LIVE_LOCK, &gfs2_nondisk_glops, LM_ST_SHARED, - LM_FLAG_NOEXP | GL_EXACT, + LM_FLAG_NOEXP | GL_EXACT | GL_NOPID, &sdp->sd_live_gh); if (error) { fs_err(sdp, "can't acquire live glock: %d\n", error); @@ -689,7 +690,7 @@ static int init_statfs(struct gfs2_sbd *sdp) iput(pn); pn = NULL; ip = GFS2_I(sdp->sd_sc_inode); - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_NOPID, &sdp->sd_sc_gh); if (error) { fs_err(sdp, "can't lock local \"sc\" file: %d\n", error); @@ -778,7 +779,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) error = gfs2_glock_nq_num(sdp, sdp->sd_lockstruct.ls_jid, &gfs2_journal_glops, LM_ST_EXCLUSIVE, - LM_FLAG_NOEXP | GL_NOCACHE, + LM_FLAG_NOEXP | GL_NOCACHE | GL_NOPID, &sdp->sd_journal_gh); if (error) { fs_err(sdp, "can't acquire journal glock: %d\n", error); @@ -788,7 +789,8 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) ip = GFS2_I(sdp->sd_jdesc->jd_inode); sdp->sd_jinode_gl = ip->i_gl; error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, - LM_FLAG_NOEXP | GL_EXACT | GL_NOCACHE, + LM_FLAG_NOEXP | GL_EXACT | + GL_NOCACHE | GL_NOPID, &sdp->sd_jinode_gh); if (error) { fs_err(sdp, "can't acquire journal inode glock: %d\n", @@ -959,7 +961,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo) pn = NULL; ip = GFS2_I(sdp->sd_qc_inode); - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_NOPID, &sdp->sd_qc_gh); if (error) { fs_err(sdp, "can't lock local \"qc\" file: %d\n", error); diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index bdb773e5c88f..90db4a289269 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -346,7 +346,8 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp) } error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE, - LM_FLAG_NOEXP, &sdp->sd_freeze_gh); + LM_FLAG_NOEXP | GL_NOPID, + &sdp->sd_freeze_gh); if (error) goto out; diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 8241029a2a5d..95d733dd3c25 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c @@ -226,7 +226,8 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp) */ fs_warn(sdp, "Requesting recovery of jid %d.\n", sdp->sd_lockstruct.ls_jid); - gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | LM_FLAG_NOEXP, + gfs2_holder_reinit(LM_ST_EXCLUSIVE, + LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | GL_NOPID, &sdp->sd_live_gh); msleep(GL_GLOCK_MAX_HOLD); /* @@ -251,7 +252,8 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp) fs_warn(sdp, "Unable to recover our journal jid %d.\n", sdp->sd_lockstruct.ls_jid); gfs2_glock_dq_wait(&sdp->sd_live_gh); - gfs2_holder_reinit(LM_ST_SHARED, LM_FLAG_NOEXP | GL_EXACT, + gfs2_holder_reinit(LM_ST_SHARED, + LM_FLAG_NOEXP | GL_EXACT | GL_NOPID, &sdp->sd_live_gh); gfs2_glock_nq(&sdp->sd_live_gh); } From 84261749e58a13e3287f948b61e6e453cca8ae9b Mon Sep 17 00:00:00 2001 From: Tomer Maimon Date: Sun, 17 Jul 2022 15:11:23 +0300 Subject: [PATCH 006/401] dt-bindings: ipmi: Add npcm845 compatible Add a compatible string for Nuvoton BMC NPCM845 KCS and modify NPCM KCS description to support all NPCM BMC SoC. Signed-off-by: Tomer Maimon Message-Id: <20220717121124.154734-2-tmaimon77@gmail.com> Acked-by: Krzysztof Kozlowski Signed-off-by: Corey Minyard --- Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt index 352f5e9c759b..cbc10a68ddef 100644 --- a/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt +++ b/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt @@ -1,12 +1,13 @@ -* Nuvoton NPCM7xx KCS (Keyboard Controller Style) IPMI interface +* Nuvoton NPCM KCS (Keyboard Controller Style) IPMI interface -The Nuvoton SOCs (NPCM7xx) are commonly used as BMCs +The Nuvoton SOCs (NPCM) are commonly used as BMCs (Baseboard Management Controllers) and the KCS interface can be used to perform in-band IPMI communication with their host. Required properties: - compatible : should be one of "nuvoton,npcm750-kcs-bmc" + "nuvoton,npcm845-kcs-bmc" - interrupts : interrupt generated by the controller - kcs_chan : The KCS channel number in the controller From dfef1acc36d56d947a69ff57bf03fa0a0f276b7c Mon Sep 17 00:00:00 2001 From: Tomer Maimon Date: Sun, 17 Jul 2022 15:11:24 +0300 Subject: [PATCH 007/401] char: ipmi: modify NPCM KCS configuration Modify NPCM IPMI KCS configuration to support all NPCM BMC SoC. Signed-off-by: Tomer Maimon Message-Id: <20220717121124.154734-3-tmaimon77@gmail.com> Signed-off-by: Corey Minyard --- drivers/char/ipmi/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index b061e6b513ed..39565cf74b2c 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -119,13 +119,13 @@ config ASPEED_KCS_IPMI_BMC provides the access of KCS IO space for BMC side. config NPCM7XX_KCS_IPMI_BMC - depends on ARCH_NPCM7XX || COMPILE_TEST + depends on ARCH_NPCM || COMPILE_TEST select IPMI_KCS_BMC select REGMAP_MMIO - tristate "NPCM7xx KCS IPMI BMC driver" + tristate "NPCM KCS IPMI BMC driver" help Provides a driver for the KCS (Keyboard Controller Style) IPMI - interface found on Nuvoton NPCM7xx SOCs. + interface found on Nuvoton NPCM SOCs. The driver implements the BMC side of the KCS contorller, it provides the access of KCS IO space for BMC side. From 79c87b8f8ba7e5706aa5cb2601635b468820e911 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 15 Jul 2022 13:41:56 +0800 Subject: [PATCH 008/401] ipmi: Fix comment typo The double `the' is duplicated in line 4360, remove one. Signed-off-by: Jason Wang Message-Id: <20220715054156.6342-1-wangborong@cdjrlc.com> Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_msghandler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 703433493c85..c8a3b208f923 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -4357,7 +4357,7 @@ static int handle_oem_get_msg_cmd(struct ipmi_smi *intf, /* * The message starts at byte 4 which follows the - * the Channel Byte in the "GET MESSAGE" command + * Channel Byte in the "GET MESSAGE" command */ recv_msg->msg.data_len = msg->rsp_size - 4; memcpy(recv_msg->msg_data, &msg->rsp[4], From 938db76cf8c8d2bd7c56aca74bef68d443e76954 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Aug 2022 10:16:14 -0700 Subject: [PATCH 009/401] Input: elan_i2c - convert to use dev_groups There is no need for a driver to individually add/create device groups, the driver core will do it automatically for you. Convert the elan_i2c driver to use the dev_groups pointer instead of manually calling the driver core to create the group and have it be cleaned up later on by the devm core. Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20220802162854.3015369-1-gregkh@linuxfoundation.org Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elan_i2c_core.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index e1758d5ffe42..d4eb59b55bf1 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -1311,12 +1311,6 @@ static int elan_probe(struct i2c_client *client, return error; } - error = devm_device_add_groups(dev, elan_sysfs_groups); - if (error) { - dev_err(dev, "failed to create sysfs attributes: %d\n", error); - return error; - } - error = input_register_device(data->input); if (error) { dev_err(dev, "failed to register input device: %d\n", error); @@ -1442,6 +1436,7 @@ static struct i2c_driver elan_driver = { .acpi_match_table = ACPI_PTR(elan_acpi_id), .of_match_table = of_match_ptr(elan_of_match), .probe_type = PROBE_PREFER_ASYNCHRONOUS, + .dev_groups = elan_sysfs_groups, }, .probe = elan_probe, .id_table = elan_id, From 4aebcc9059d890bf2f438cfa169dad856123fc9c Mon Sep 17 00:00:00 2001 From: Tomer Maimon Date: Mon, 8 Aug 2022 10:54:52 +0300 Subject: [PATCH 010/401] dt-binding: ipmi: add fallback to npcm845 compatible Add to npcm845 KCS compatible string a fallback to npcm750 KCS compatible string becuase NPCM845 and NPCM750 BMCs are using identical KCS modules. Fixes: 84261749e58a ("dt-bindings: ipmi: Add npcm845 compatible") Signed-off-by: Tomer Maimon Message-Id: <20220808075452.115907-1-tmaimon77@gmail.com> Acked-by: Krzysztof Kozlowski Signed-off-by: Corey Minyard --- Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt index cbc10a68ddef..4fda76e63396 100644 --- a/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt +++ b/Documentation/devicetree/bindings/ipmi/npcm7xx-kcs-bmc.txt @@ -7,7 +7,7 @@ used to perform in-band IPMI communication with their host. Required properties: - compatible : should be one of "nuvoton,npcm750-kcs-bmc" - "nuvoton,npcm845-kcs-bmc" + "nuvoton,npcm845-kcs-bmc", "nuvoton,npcm750-kcs-bmc" - interrupts : interrupt generated by the controller - kcs_chan : The KCS channel number in the controller From 9900d9249f736bcd474f56e935db2c70977756ba Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Tue, 26 Jul 2022 14:56:06 +0200 Subject: [PATCH 011/401] MAINTAINERS: input: add mattijs for mt6779-keypad As stated in [1]: Fengping has no longer interest and time to maintain this driver so he agreed to transfer maintainership over to me. Add a dedicated maintainer entry as well for the driver to make sure that I can help with patch reviews. [1] https://lore.kernel.org/r/20220421140255.2781505-1-mkorpershoek@baylibre.com Signed-off-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20220720-mt8183-keypad-v2-1-6d42c357cb76@baylibre.com Signed-off-by: Dmitry Torokhov --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 66bffb24a348..5cff72980872 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12553,6 +12553,12 @@ S: Supported F: Documentation/devicetree/bindings/media/mediatek-jpeg-*.yaml F: drivers/media/platform/mediatek/jpeg/ +MEDIATEK KEYPAD DRIVER +M: Mattijs Korpershoek +S: Supported +F: Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml +F: drivers/input/keyboard/mt6779-keypad.c + MEDIATEK MDP DRIVER M: Minghsiu Tsai M: Houlong Wei From fe2281d630e0ae375d8d53f3ccff21f444ab64c8 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Tue, 26 Jul 2022 14:56:07 +0200 Subject: [PATCH 012/401] dt-bindings: mediatek,mt6779-keypad: use unevaluatedProperties writing-bindings.rst states: > - If schema includes other schema (e.g. /schemas/i2c/i2c-controller.yaml) use > "unevaluatedProperties:false". In other cases, usually use > "additionalProperties:false". All 3 properties from matrix-keymap.yaml are valid for the MediaTek keypad: * keypad,num-rows and keypad,num-cols configure the KP_SEL register * linux,keymap represents the (at most) 8x8 hardware matrix Signed-off-by: Mattijs Korpershoek Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220720-mt8183-keypad-v2-2-6d42c357cb76@baylibre.com Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/mediatek,mt6779-keypad.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml index 03ebd2665d07..ca8ae40a73f7 100644 --- a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml +++ b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml @@ -56,7 +56,7 @@ required: - clocks - clock-names -additionalProperties: false +unevaluatedProperties: false examples: - | From 24f9cde381a7781f9f58191217989f7de98c5cd8 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Tue, 26 Jul 2022 14:56:08 +0200 Subject: [PATCH 013/401] dt-bindings: mediatek,mt6779-keypad: add mediatek,keys-per-group The MediaTek keypad has 2 modes of detecting key events: * single key: each (row, column) can detect one key * double key: each (row, column) is a group of 2 keys With double key, two keys are physically wired to one (row, column) pin. These keys are in the same "group". Multiple keys in the same group reduces the number of pins which minimizes cost. Add a keys-per-group property to describe this. Signed-off-by: Mattijs Korpershoek Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220720-mt8183-keypad-v2-3-6d42c357cb76@baylibre.com Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/mediatek,mt6779-keypad.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml index ca8ae40a73f7..387d0448ff77 100644 --- a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml +++ b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml @@ -49,6 +49,12 @@ properties: maximum: 256 default: 16 + mediatek,keys-per-group: + description: each (row, column) group has multiple keys + $ref: /schemas/types.yaml#/definitions/uint32 + default: 1 + maximum: 2 + required: - compatible - reg From e76be36ad9e8560f6d1b02ad12dc912eaa19ddd1 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Tue, 26 Jul 2022 14:56:09 +0200 Subject: [PATCH 014/401] Input: mt6779-keypad - prepare double keys support with calc_row_col The MediaTek keypad can operate in two modes: single key or double key. The driver only supports single key mode. In double key mode, the row/column calculation based on the key is different. Add a calc_row_col function pointer which will be different based on single/double key mode. No functional change. Suggested-by: AngeloGioacchino Del Regno Signed-off-by: Mattijs Korpershoek Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220720-mt8183-keypad-v2-4-6d42c357cb76@baylibre.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mt6779-keypad.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/input/keyboard/mt6779-keypad.c b/drivers/input/keyboard/mt6779-keypad.c index bf447bf598fb..9decdfa68555 100644 --- a/drivers/input/keyboard/mt6779-keypad.c +++ b/drivers/input/keyboard/mt6779-keypad.c @@ -31,6 +31,8 @@ struct mt6779_keypad { struct clk *clk; u32 n_rows; u32 n_cols; + void (*calc_row_col)(unsigned int key, + unsigned int *row, unsigned int *col); DECLARE_BITMAP(keymap_state, MTK_KPD_NUM_BITS); }; @@ -67,8 +69,7 @@ static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id) continue; key = bit_nr / 32 * 16 + bit_nr % 32; - row = key / 9; - col = key % 9; + keypad->calc_row_col(key, &row, &col); scancode = MATRIX_SCAN_CODE(row, col, row_shift); /* 1: not pressed, 0: pressed */ @@ -94,6 +95,14 @@ static void mt6779_keypad_clk_disable(void *data) clk_disable_unprepare(data); } +static void mt6779_keypad_calc_row_col_single(unsigned int key, + unsigned int *row, + unsigned int *col) +{ + *row = key / 9; + *col = key % 9; +} + static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) { struct mt6779_keypad *keypad; @@ -148,6 +157,8 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) return -EINVAL; } + keypad->calc_row_col = mt6779_keypad_calc_row_col_single; + wakeup = device_property_read_bool(&pdev->dev, "wakeup-source"); dev_dbg(&pdev->dev, "n_row=%d n_col=%d debounce=%d\n", From 51c88597517d9625c127f0d8f8f3bf04ef5f8d76 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Tue, 26 Jul 2022 14:56:10 +0200 Subject: [PATCH 015/401] Input: mt6779-keypad - support double keys matrix MediaTek keypad has 2 modes of detecting key events: - single key: each (row, column) can detect one key - double key: each (row, column) is a group of 2 keys Double key support exists to minimize cost, since it reduces the number of pins required for physical keys. Double key is configured by setting BIT(0) of the KP_SEL register. Enable double key matrix support based on the mediatek,keys-per-group device tree property. Signed-off-by: Mattijs Korpershoek Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220720-mt8183-keypad-v2-5-6d42c357cb76@baylibre.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mt6779-keypad.c | 32 +++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/input/keyboard/mt6779-keypad.c b/drivers/input/keyboard/mt6779-keypad.c index 9decdfa68555..a05e70af1fd0 100644 --- a/drivers/input/keyboard/mt6779-keypad.c +++ b/drivers/input/keyboard/mt6779-keypad.c @@ -18,6 +18,7 @@ #define MTK_KPD_DEBOUNCE_MASK GENMASK(13, 0) #define MTK_KPD_DEBOUNCE_MAX_MS 256 #define MTK_KPD_SEL 0x0020 +#define MTK_KPD_SEL_DOUBLE_KP_MODE BIT(0) #define MTK_KPD_SEL_COL GENMASK(15, 10) #define MTK_KPD_SEL_ROW GENMASK(9, 4) #define MTK_KPD_SEL_COLMASK(c) GENMASK((c) + 9, 10) @@ -103,12 +104,21 @@ static void mt6779_keypad_calc_row_col_single(unsigned int key, *col = key % 9; } +static void mt6779_keypad_calc_row_col_double(unsigned int key, + unsigned int *row, + unsigned int *col) +{ + *row = key / 13; + *col = (key % 13) / 2; +} + static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) { struct mt6779_keypad *keypad; void __iomem *base; int irq; u32 debounce; + u32 keys_per_group; bool wakeup; int error; @@ -157,7 +167,22 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) return -EINVAL; } - keypad->calc_row_col = mt6779_keypad_calc_row_col_single; + if (device_property_read_u32(&pdev->dev, "mediatek,keys-per-group", + &keys_per_group)) + keys_per_group = 1; + + switch (keys_per_group) { + case 1: + keypad->calc_row_col = mt6779_keypad_calc_row_col_single; + break; + case 2: + keypad->calc_row_col = mt6779_keypad_calc_row_col_double; + break; + default: + dev_err(&pdev->dev, + "Invalid keys-per-group: %d\n", keys_per_group); + return -EINVAL; + } wakeup = device_property_read_bool(&pdev->dev, "wakeup-source"); @@ -177,6 +202,11 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE, (debounce * (1 << 5)) & MTK_KPD_DEBOUNCE_MASK); + if (keys_per_group == 2) + regmap_update_bits(keypad->regmap, MTK_KPD_SEL, + MTK_KPD_SEL_DOUBLE_KP_MODE, + MTK_KPD_SEL_DOUBLE_KP_MODE); + regmap_update_bits(keypad->regmap, MTK_KPD_SEL, MTK_KPD_SEL_ROW, MTK_KPD_SEL_ROWMASK(keypad->n_rows)); regmap_update_bits(keypad->regmap, MTK_KPD_SEL, MTK_KPD_SEL_COL, From fb12ad5e3179c9667dfcbafe2c5da91f9e700e53 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 11 Aug 2022 16:11:36 -0700 Subject: [PATCH 016/401] Input: bma150 - fix a typo in some comments Remove some extra '0' s/BMA0150_RANGE_xxx/BMA150_RANGE_xxx/ s/BMA0150_BW_xxx/BMA150_BW_xxx Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/a331a6244a1dfbf34dc85f1be6995fa91500c801.1659802757.git.christophe.jaillet@wanadoo.fr Signed-off-by: Dmitry Torokhov --- include/linux/bma150.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/bma150.h b/include/linux/bma150.h index 31c9e323a391..4d4a62d49341 100644 --- a/include/linux/bma150.h +++ b/include/linux/bma150.h @@ -33,8 +33,8 @@ struct bma150_cfg { unsigned char lg_hyst; /* Low-G hysterisis */ unsigned char lg_dur; /* Low-G duration */ unsigned char lg_thres; /* Low-G threshold */ - unsigned char range; /* one of BMA0150_RANGE_xxx */ - unsigned char bandwidth; /* one of BMA0150_BW_xxx */ + unsigned char range; /* one of BMA150_RANGE_xxx */ + unsigned char bandwidth; /* one of BMA150_BW_xxx */ }; struct bma150_platform_data { From 6a33af349b1b977e8e2298ed131a46316bcb3e62 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 11 Aug 2022 16:11:59 -0700 Subject: [PATCH 017/401] Input: tc3589x-keypad - use correct struct names in comment The incorrect structure name is being used in the comment for struct tc3589x_keypad_platform_data. Correct it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20220805174717.2374416-1-colin.i.king@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tc3589x-keypad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index 89b9575dc75d..78e55318ccd6 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c @@ -70,7 +70,7 @@ #define TC3589x_KBD_INT_CLR 0x1 /** - * struct tc35893_keypad_platform_data - platform specific keypad data + * struct tc3589x_keypad_platform_data - platform specific keypad data * @keymap_data: matrix scan code table for keycodes * @krow: mask for available rows, value is 0xFF * @kcol: mask for available columns, value is 0xFF From 93e719f661379c014f44bd83b361b1bc49ea7082 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 11 Aug 2022 16:12:37 -0700 Subject: [PATCH 018/401] Input: applespi - use correct struct names in comment The incorrect structure name is being used in the comment for struct touchpad_info_protocol. Correct it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20220805174754.2374473-1-colin.i.king@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/applespi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c index d1f5354d5ea2..fcf4b55cdf90 100644 --- a/drivers/input/keyboard/applespi.c +++ b/drivers/input/keyboard/applespi.c @@ -202,7 +202,7 @@ struct command_protocol_tp_info { }; /** - * struct touchpad_info - touchpad info response. + * struct touchpad_info_protocol - touchpad info response. * message.type = 0x1020, message.length = 0x006e * * @unknown1: unknown From 96355be8f0a2a7a91aae2e66c0795a13444db5ba Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 26 Jul 2022 18:53:15 +0100 Subject: [PATCH 019/401] dt-bindings: pinctrl: renesas: Document RZ/Five SoC RZ/Five SoC is pin compatible with RZ/G2UL (Type 1) SoC. This patch updates the comment to include RZ/Five SoC so that we make it clear "renesas,r9a07g043-pinctrl" compatible string will be used for RZ/Five SoC. Signed-off-by: Lad Prabhakar Link: https://lore.kernel.org/r/20220726175315.1147-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml index 997b74639112..f081acb7ba04 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml @@ -23,7 +23,7 @@ properties: oneOf: - items: - enum: - - renesas,r9a07g043-pinctrl # RZ/G2UL{Type-1,Type-2} + - renesas,r9a07g043-pinctrl # RZ/G2UL{Type-1,Type-2} and RZ/Five - renesas,r9a07g044-pinctrl # RZ/G2{L,LC} - items: From 152a81a0b1204e9c7f4af0004b5ed7a8d67dd037 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Tue, 26 Jul 2022 18:33:48 -0700 Subject: [PATCH 020/401] pinctrl: samsung: Finish initializing the gpios before registering them As soon as a gpio is registered, it should be usable by a consumer. So, do all the initialization before registering the gpios. Without this change, a consumer can request a GPIO IRQ and have the gpio to IRQ mapping fail. Signed-off-by: Saravana Kannan Reviewed-by: Sam Protsenko Reviewed-by: Chanho Park Tested-by: Chanho Park Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220727013349.3056826-1-saravanak@google.com --- drivers/pinctrl/samsung/pinctrl-samsung.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 4837bceb767b..bd13b5ef246d 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1166,15 +1166,15 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) if (ret) goto err_put_banks; - ret = samsung_gpiolib_register(pdev, drvdata); - if (ret) - goto err_unregister; - if (ctrl->eint_gpio_init) ctrl->eint_gpio_init(drvdata); if (ctrl->eint_wkup_init) ctrl->eint_wkup_init(drvdata); + ret = samsung_gpiolib_register(pdev, drvdata); + if (ret) + goto err_unregister; + platform_set_drvdata(pdev, drvdata); return 0; From bc604fbb49f1a00df34e6755a32e8bf5419eb4cd Mon Sep 17 00:00:00 2001 From: Eddie James Date: Fri, 12 Aug 2022 15:32:27 -0700 Subject: [PATCH 021/401] dt-bindings: input: Add documentation for IBM Operation Panel Document the bindings for the IBM Operation Panel, which provides a simple interface to control a server. It has a display and three buttons. Also update MAINTAINERS for the new file. Signed-off-by: Eddie James Reviewed-by: Rob Herring Acked-by: Joel Stanley Link: https://lore.kernel.org/r/20220809204147.238132-2-eajames@linux.ibm.com Signed-off-by: Dmitry Torokhov --- .../bindings/input/ibm,op-panel.yaml | 50 +++++++++++++++++++ MAINTAINERS | 6 +++ 2 files changed, 56 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/ibm,op-panel.yaml diff --git a/Documentation/devicetree/bindings/input/ibm,op-panel.yaml b/Documentation/devicetree/bindings/input/ibm,op-panel.yaml new file mode 100644 index 000000000000..29a1879e356d --- /dev/null +++ b/Documentation/devicetree/bindings/input/ibm,op-panel.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/ibm,op-panel.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: IBM Operation Panel + +maintainers: + - Eddie James + +allOf: + - $ref: input.yaml# + +description: | + The IBM Operation Panel provides a simple interface to control the connected + server. It has a display and three buttons: two directional arrows and one + 'Enter' button. + +properties: + compatible: + const: ibm,op-panel + + reg: + maxItems: 1 + + linux,keycodes: + minItems: 1 + maxItems: 3 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ibm-op-panel@62 { + compatible = "ibm,op-panel"; + reg = <(0x62 | I2C_OWN_SLAVE_ADDRESS)>; + linux,keycodes = , , ; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 2910c5e50ac0..084a8728953a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9643,6 +9643,12 @@ S: Orphan F: Documentation/ia64/ F: arch/ia64/ +IBM Operation Panel Input Driver +M: Eddie James +L: linux-input@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/input/ibm,op-panel.yaml + IBM Power 842 compression accelerator M: Haren Myneni S: Supported From 2e6f34faa7e0158b8eb432b44082bac23c63f8bf Mon Sep 17 00:00:00 2001 From: Eddie James Date: Fri, 12 Aug 2022 15:32:39 -0700 Subject: [PATCH 022/401] Input: Add IBM Operation Panel driver Add a driver to get the button events from the panel and provide them to userspace with the input subsystem. The panel is connected with I2C and controls the bus, so the driver registers as an I2C slave device. Signed-off-by: Eddie James Reviewed-by: Joel Stanley Reviewed-by: Wolfram Sang # I2C slave parts Link: https://lore.kernel.org/r/20220809204147.238132-3-eajames@linux.ibm.com Signed-off-by: Dmitry Torokhov --- MAINTAINERS | 1 + drivers/input/misc/Kconfig | 18 +++ drivers/input/misc/Makefile | 1 + drivers/input/misc/ibm-panel.c | 199 +++++++++++++++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 drivers/input/misc/ibm-panel.c diff --git a/MAINTAINERS b/MAINTAINERS index 084a8728953a..711bcd4f6269 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9648,6 +9648,7 @@ M: Eddie James L: linux-input@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/input/ibm,op-panel.yaml +F: drivers/input/misc/ibm-panel.c IBM Power 842 compression accelerator M: Haren Myneni diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index a18ab7358d8f..968240288c61 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -730,6 +730,24 @@ config INPUT_ADXL34X_SPI To compile this driver as a module, choose M here: the module will be called adxl34x-spi. +config INPUT_IBM_PANEL + tristate "IBM Operation Panel driver" + depends on I2C && I2C_SLAVE + help + Say Y here if you have an IBM Operation Panel connected to your system + over I2C. The panel is typically connected only to a system's service + processor (BMC). + + If unsure, say N. + + The Operation Panel is a controller with some buttons and an LCD + display that allows someone with physical access to the system to + perform various administrative tasks. This driver only supports the part + of the controller that sends commands to the system. + + To compile this driver as a module, choose M here: the module will be + called ibm-panel. + config INPUT_IMS_PCU tristate "IMS Passenger Control Unit driver" depends on USB diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 28dfc444f0a9..9eea13e98d48 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_INPUT_GPIO_DECODER) += gpio_decoder.o obj-$(CONFIG_INPUT_GPIO_VIBRA) += gpio-vibra.o obj-$(CONFIG_INPUT_HISI_POWERKEY) += hisi_powerkey.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o +obj-$(CONFIG_INPUT_IBM_PANEL) += ibm-panel.o obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o obj-$(CONFIG_INPUT_IQS269A) += iqs269a.o obj-$(CONFIG_INPUT_IQS626A) += iqs626a.o diff --git a/drivers/input/misc/ibm-panel.c b/drivers/input/misc/ibm-panel.c new file mode 100644 index 000000000000..094bcdb568f1 --- /dev/null +++ b/drivers/input/misc/ibm-panel.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) IBM Corporation 2020 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "ibm-panel" +#define PANEL_KEYCODES_COUNT 3 + +struct ibm_panel { + u8 idx; + u8 command[11]; + u32 keycodes[PANEL_KEYCODES_COUNT]; + spinlock_t lock; /* protects writes to idx and command */ + struct input_dev *input; +}; + +static u8 ibm_panel_calculate_checksum(struct ibm_panel *panel) +{ + u8 chksum; + u16 sum = 0; + unsigned int i; + + for (i = 0; i < sizeof(panel->command) - 1; ++i) { + sum += panel->command[i]; + if (sum & 0xff00) { + sum &= 0xff; + sum++; + } + } + + chksum = sum & 0xff; + chksum = ~chksum; + chksum++; + + return chksum; +} + +static void ibm_panel_process_command(struct ibm_panel *panel) +{ + u8 button; + u8 chksum; + + if (panel->command[0] != 0xff && panel->command[1] != 0xf0) { + dev_dbg(&panel->input->dev, "command invalid: %02x %02x\n", + panel->command[0], panel->command[1]); + return; + } + + chksum = ibm_panel_calculate_checksum(panel); + if (chksum != panel->command[sizeof(panel->command) - 1]) { + dev_dbg(&panel->input->dev, + "command failed checksum: %u != %u\n", chksum, + panel->command[sizeof(panel->command) - 1]); + return; + } + + button = panel->command[2] & 0xf; + if (button < PANEL_KEYCODES_COUNT) { + input_report_key(panel->input, panel->keycodes[button], + !(panel->command[2] & 0x80)); + input_sync(panel->input); + } else { + dev_dbg(&panel->input->dev, "unknown button %u\n", + button); + } +} + +static int ibm_panel_i2c_slave_cb(struct i2c_client *client, + enum i2c_slave_event event, u8 *val) +{ + unsigned long flags; + struct ibm_panel *panel = i2c_get_clientdata(client); + + dev_dbg(&panel->input->dev, "event: %u data: %02x\n", event, *val); + + spin_lock_irqsave(&panel->lock, flags); + + switch (event) { + case I2C_SLAVE_STOP: + if (panel->idx == sizeof(panel->command)) + ibm_panel_process_command(panel); + else + dev_dbg(&panel->input->dev, + "command incorrect size %u\n", panel->idx); + fallthrough; + case I2C_SLAVE_WRITE_REQUESTED: + panel->idx = 0; + break; + case I2C_SLAVE_WRITE_RECEIVED: + if (panel->idx < sizeof(panel->command)) + panel->command[panel->idx++] = *val; + else + /* + * The command is too long and therefore invalid, so set the index + * to it's largest possible value. When a STOP is finally received, + * the command will be rejected upon processing. + */ + panel->idx = U8_MAX; + break; + case I2C_SLAVE_READ_REQUESTED: + case I2C_SLAVE_READ_PROCESSED: + *val = 0xff; + break; + default: + break; + } + + spin_unlock_irqrestore(&panel->lock, flags); + + return 0; +} + +static int ibm_panel_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ibm_panel *panel; + int i; + int error; + + panel = devm_kzalloc(&client->dev, sizeof(*panel), GFP_KERNEL); + if (!panel) + return -ENOMEM; + + spin_lock_init(&panel->lock); + + panel->input = devm_input_allocate_device(&client->dev); + if (!panel->input) + return -ENOMEM; + + panel->input->name = client->name; + panel->input->id.bustype = BUS_I2C; + + error = device_property_read_u32_array(&client->dev, + "linux,keycodes", + panel->keycodes, + PANEL_KEYCODES_COUNT); + if (error) { + /* + * Use gamepad buttons as defaults for compatibility with + * existing applications. + */ + panel->keycodes[0] = BTN_NORTH; + panel->keycodes[1] = BTN_SOUTH; + panel->keycodes[2] = BTN_SELECT; + } + + for (i = 0; i < PANEL_KEYCODES_COUNT; ++i) + input_set_capability(panel->input, EV_KEY, panel->keycodes[i]); + + error = input_register_device(panel->input); + if (error) { + dev_err(&client->dev, + "Failed to register input device: %d\n", error); + return error; + } + + i2c_set_clientdata(client, panel); + error = i2c_slave_register(client, ibm_panel_i2c_slave_cb); + if (error) { + dev_err(&client->dev, + "Failed to register as i2c slave: %d\n", error); + return error; + } + + return 0; +} + +static void ibm_panel_remove(struct i2c_client *client) +{ + i2c_slave_unregister(client); +} + +static const struct of_device_id ibm_panel_match[] = { + { .compatible = "ibm,op-panel" }, + { } +}; + +static struct i2c_driver ibm_panel_driver = { + .driver = { + .name = DEVICE_NAME, + .of_match_table = ibm_panel_match, + }, + .probe = ibm_panel_probe, + .remove = ibm_panel_remove, +}; +module_i2c_driver(ibm_panel_driver); + +MODULE_AUTHOR("Eddie James "); +MODULE_DESCRIPTION("IBM Operation Panel Driver"); +MODULE_LICENSE("GPL"); From c42a5ff530a7e2122ed8fb576ddf16a18730ef05 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Tue, 16 Aug 2022 14:16:36 -0700 Subject: [PATCH 023/401] dt-bindings: adc-joystick: add poll-interval Add poll-interval support for the adc-joystick documentation. This is an optional value and if not provided the adc-joystick works as it does today (with buffers). If this value is provided, the adc-joystick driver is polled at the specified interval. The existing attribute of "poll-interval" was used instead of complying with property-units.yaml after discussion of the issue on the mailing list. Signed-off-by: Maya Matuszczyk Signed-off-by: Chris Morgan Reviewed-by: Rob Herring Acked-by: Artur Rojek Link: https://lore.kernel.org/r/20220816210440.14260-2-macroalpha82@gmail.com Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/input/adc-joystick.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/input/adc-joystick.yaml b/Documentation/devicetree/bindings/input/adc-joystick.yaml index 64d961458ac7..da0f8dfca8bf 100644 --- a/Documentation/devicetree/bindings/input/adc-joystick.yaml +++ b/Documentation/devicetree/bindings/input/adc-joystick.yaml @@ -14,6 +14,9 @@ description: > Bindings for joystick devices connected to ADC controllers supporting the Industrial I/O subsystem. +allOf: + - $ref: input.yaml# + properties: compatible: const: adc-joystick @@ -28,6 +31,8 @@ properties: https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml for details. + poll-interval: true + '#address-cells': const: 1 From 24c06e000e8fa237ff2d960def0768a47d0db7b1 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Tue, 16 Aug 2022 14:16:54 -0700 Subject: [PATCH 024/401] Input: adc-joystick - add polled input device support Add polled input device support to the adc-joystick driver. This is useful for devices which do not have hardware capable triggers on their SARADC. Code modified from adc-joystick.c changes made by Maya Matuszczyk. Signed-off-by: Maya Matuszczyk Signed-off-by: Chris Morgan Link: https://lore.kernel.org/r/20220816210440.14260-3-macroalpha82@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/adc-joystick.c | 65 ++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/drivers/input/joystick/adc-joystick.c b/drivers/input/joystick/adc-joystick.c index e0cfdc84763f..c0deff5d4282 100644 --- a/drivers/input/joystick/adc-joystick.c +++ b/drivers/input/joystick/adc-joystick.c @@ -26,8 +26,23 @@ struct adc_joystick { struct adc_joystick_axis *axes; struct iio_channel *chans; int num_chans; + bool polled; }; +static void adc_joystick_poll(struct input_dev *input) +{ + struct adc_joystick *joy = input_get_drvdata(input); + int i, val, ret; + + for (i = 0; i < joy->num_chans; i++) { + ret = iio_read_channel_raw(&joy->chans[i], &val); + if (ret < 0) + return; + input_report_abs(input, joy->axes[i].code, val); + } + input_sync(input); +} + static int adc_joystick_handle(const void *data, void *private) { struct adc_joystick *joy = private; @@ -179,6 +194,7 @@ static int adc_joystick_probe(struct platform_device *pdev) int error; int bits; int i; + unsigned int poll_interval; joy = devm_kzalloc(dev, sizeof(*joy), GFP_KERNEL); if (!joy) @@ -192,8 +208,25 @@ static int adc_joystick_probe(struct platform_device *pdev) return error; } - /* Count how many channels we got. NULL terminated. */ + error = device_property_read_u32(dev, "poll-interval", &poll_interval); + if (error) { + /* -EINVAL means the property is absent. */ + if (error != -EINVAL) + return error; + } else if (poll_interval == 0) { + dev_err(dev, "Unable to get poll-interval\n"); + return -EINVAL; + } else { + joy->polled = true; + } + + /* + * Count how many channels we got. NULL terminated. + * Do not check the storage size if using polling. + */ for (i = 0; joy->chans[i].indio_dev; i++) { + if (joy->polled) + continue; bits = joy->chans[i].channel->scan_type.storagebits; if (!bits || bits > 16) { dev_err(dev, "Unsupported channel storage size\n"); @@ -215,23 +248,31 @@ static int adc_joystick_probe(struct platform_device *pdev) joy->input = input; input->name = pdev->name; input->id.bustype = BUS_HOST; - input->open = adc_joystick_open; - input->close = adc_joystick_close; error = adc_joystick_set_axes(dev, joy); if (error) return error; - joy->buffer = iio_channel_get_all_cb(dev, adc_joystick_handle, joy); - if (IS_ERR(joy->buffer)) { - dev_err(dev, "Unable to allocate callback buffer\n"); - return PTR_ERR(joy->buffer); - } + if (joy->polled) { + input_setup_polling(input, adc_joystick_poll); + input_set_poll_interval(input, poll_interval); + } else { + input->open = adc_joystick_open; + input->close = adc_joystick_close; - error = devm_add_action_or_reset(dev, adc_joystick_cleanup, joy->buffer); - if (error) { - dev_err(dev, "Unable to add action\n"); - return error; + joy->buffer = iio_channel_get_all_cb(dev, adc_joystick_handle, + joy); + if (IS_ERR(joy->buffer)) { + dev_err(dev, "Unable to allocate callback buffer\n"); + return PTR_ERR(joy->buffer); + } + + error = devm_add_action_or_reset(dev, adc_joystick_cleanup, + joy->buffer); + if (error) { + dev_err(dev, "Unable to add action\n"); + return error; + } } input_set_drvdata(input, joy); From a9f08ad7adb3d2f90e11efbb40a1246ef95b0c04 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 18 Aug 2022 15:05:06 -0700 Subject: [PATCH 025/401] Input: move from strlcpy with unused retval to strscpy Follow the advice of the below link and prefer 'strscpy' in this subsystem. Conversion is 1:1 because the return value is not used. Generated by a coccinelle script. Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20220818210022.6865-1-wsa+renesas@sang-engineering.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/lkkbd.c | 8 ++++---- drivers/input/misc/keyspan_remote.c | 2 +- drivers/input/mouse/hgpk.c | 2 +- drivers/input/mouse/synaptics.c | 4 ++-- drivers/input/mouse/synaptics_usb.c | 2 +- drivers/input/mouse/vsxxxaa.c | 4 ++-- drivers/input/rmi4/rmi_f03.c | 2 +- drivers/input/rmi4/rmi_f54.c | 8 ++++---- drivers/input/serio/altera_ps2.c | 4 ++-- drivers/input/serio/ambakmi.c | 4 ++-- drivers/input/serio/ams_delta_serio.c | 4 ++-- drivers/input/serio/apbps2.c | 2 +- drivers/input/serio/ct82c710.c | 2 +- drivers/input/serio/gscps2.c | 2 +- drivers/input/serio/hyperv-keyboard.c | 4 ++-- drivers/input/serio/i8042-x86ia64io.h | 6 +++--- drivers/input/serio/i8042.c | 14 +++++++------- drivers/input/serio/olpc_apsp.c | 8 ++++---- drivers/input/serio/parkbd.c | 2 +- drivers/input/serio/pcips2.c | 4 ++-- drivers/input/serio/ps2-gpio.c | 4 ++-- drivers/input/serio/ps2mult.c | 2 +- drivers/input/serio/q40kbd.c | 4 ++-- drivers/input/serio/rpckbd.c | 4 ++-- drivers/input/serio/sa1111ps2.c | 4 ++-- drivers/input/serio/serport.c | 2 +- drivers/input/serio/sun4i-ps2.c | 4 ++-- drivers/input/tablet/acecad.c | 2 +- drivers/input/tablet/hanwang.c | 2 +- drivers/input/tablet/pegasus_notetaker.c | 2 +- drivers/input/touchscreen/atmel_mxt_ts.c | 8 ++++---- drivers/input/touchscreen/edt-ft5x06.c | 12 ++++++------ drivers/input/touchscreen/sur40.c | 6 +++--- drivers/input/touchscreen/usbtouchscreen.c | 2 +- drivers/input/touchscreen/wacom_w8001.c | 6 +++--- 35 files changed, 76 insertions(+), 76 deletions(-) diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index e4a1839ca934..ea9a1d8834c1 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -359,18 +359,18 @@ static void lkkbd_detection_done(struct lkkbd *lk) */ switch (lk->id[4]) { case 1: - strlcpy(lk->name, "DEC LK201 keyboard", sizeof(lk->name)); + strscpy(lk->name, "DEC LK201 keyboard", sizeof(lk->name)); if (lk201_compose_is_alt) lk->keycode[0xb1] = KEY_LEFTALT; break; case 2: - strlcpy(lk->name, "DEC LK401 keyboard", sizeof(lk->name)); + strscpy(lk->name, "DEC LK401 keyboard", sizeof(lk->name)); break; default: - strlcpy(lk->name, "Unknown DEC keyboard", sizeof(lk->name)); + strscpy(lk->name, "Unknown DEC keyboard", sizeof(lk->name)); printk(KERN_ERR "lkkbd: keyboard on %s is unknown, please report to " "Jan-Benedict Glaw \n", lk->phys); @@ -626,7 +626,7 @@ static int lkkbd_connect(struct serio *serio, struct serio_driver *drv) lk->ctrlclick_volume = ctrlclick_volume; memcpy(lk->keycode, lkkbd_keycode, sizeof(lk->keycode)); - strlcpy(lk->name, "DEC LK keyboard", sizeof(lk->name)); + strscpy(lk->name, "DEC LK keyboard", sizeof(lk->name)); snprintf(lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); input_dev->name = lk->name; diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index 4650f4a94989..bee4b1376491 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c @@ -485,7 +485,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic } if (udev->manufacturer) - strlcpy(remote->name, udev->manufacturer, sizeof(remote->name)); + strscpy(remote->name, udev->manufacturer, sizeof(remote->name)); if (udev->product) { if (udev->manufacturer) diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 4dc441309aac..523b26a117d6 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -1057,7 +1057,7 @@ void hgpk_module_init(void) strlen(hgpk_mode_name)); if (hgpk_default_mode == HGPK_MODE_INVALID) { hgpk_default_mode = HGPK_MODE_MOUSE; - strlcpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE], + strscpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE], sizeof(hgpk_mode_name)); } } diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 434d48ae4b12..e3f657713b55 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -715,8 +715,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) } serio->id.type = SERIO_PS_PSTHRU; - strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); - strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->phys)); + strscpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); + strscpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->phys)); serio->write = synaptics_pt_write; serio->start = synaptics_pt_start; serio->stop = synaptics_pt_stop; diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c index b5ff27e32a0c..75e45f3ae675 100644 --- a/drivers/input/mouse/synaptics_usb.c +++ b/drivers/input/mouse/synaptics_usb.c @@ -354,7 +354,7 @@ static int synusb_probe(struct usb_interface *intf, synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (udev->manufacturer) - strlcpy(synusb->name, udev->manufacturer, + strscpy(synusb->name, udev->manufacturer, sizeof(synusb->name)); if (udev->product) { diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index bd415f4b574e..3bd6e723a422 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -138,12 +138,12 @@ static void vsxxxaa_detection_done(struct vsxxxaa *mouse) { switch (mouse->type) { case 0x02: - strlcpy(mouse->name, "DEC VSXXX-AA/-GA mouse", + strscpy(mouse->name, "DEC VSXXX-AA/-GA mouse", sizeof(mouse->name)); break; case 0x04: - strlcpy(mouse->name, "DEC VSXXX-AB digitizer", + strscpy(mouse->name, "DEC VSXXX-AB digitizer", sizeof(mouse->name)); break; diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c index c194b1664b10..1e11ea30d7bd 100644 --- a/drivers/input/rmi4/rmi_f03.c +++ b/drivers/input/rmi4/rmi_f03.c @@ -181,7 +181,7 @@ static int rmi_f03_register_pt(struct f03_data *f03) serio->close = rmi_f03_pt_close; serio->port_data = f03; - strlcpy(serio->name, "RMI4 PS/2 pass-through", sizeof(serio->name)); + strscpy(serio->name, "RMI4 PS/2 pass-through", sizeof(serio->name)); snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", dev_name(&f03->fn->dev)); serio->dev.parent = &f03->fn->dev; diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c index c5ce907535ef..5c3da910b5b2 100644 --- a/drivers/input/rmi4/rmi_f54.c +++ b/drivers/input/rmi4/rmi_f54.c @@ -390,8 +390,8 @@ static int rmi_f54_vidioc_querycap(struct file *file, void *priv, { struct f54_data *f54 = video_drvdata(file); - strlcpy(cap->driver, F54_NAME, sizeof(cap->driver)); - strlcpy(cap->card, SYNAPTICS_INPUT_DEVICE_NAME, sizeof(cap->card)); + strscpy(cap->driver, F54_NAME, sizeof(cap->driver)); + strscpy(cap->card, SYNAPTICS_INPUT_DEVICE_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "rmi4:%s", dev_name(&f54->fn->dev)); @@ -410,7 +410,7 @@ static int rmi_f54_vidioc_enum_input(struct file *file, void *priv, i->type = V4L2_INPUT_TYPE_TOUCH; - strlcpy(i->name, rmi_f54_report_type_names[reptype], sizeof(i->name)); + strscpy(i->name, rmi_f54_report_type_names[reptype], sizeof(i->name)); return 0; } @@ -696,7 +696,7 @@ static int rmi_f54_probe(struct rmi_function *fn) rmi_f54_set_input(f54, 0); /* register video device */ - strlcpy(f54->v4l2.name, F54_NAME, sizeof(f54->v4l2.name)); + strscpy(f54->v4l2.name, F54_NAME, sizeof(f54->v4l2.name)); ret = v4l2_device_register(&fn->dev, &f54->v4l2); if (ret) { dev_err(&fn->dev, "Unable to register video dev.\n"); diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index 379e9240c2b3..3a92304f64fb 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -110,8 +110,8 @@ static int altera_ps2_probe(struct platform_device *pdev) serio->write = altera_ps2_write; serio->open = altera_ps2_open; serio->close = altera_ps2_close; - strlcpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name)); - strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys)); + strscpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name)); + strscpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys)); serio->port_data = ps2if; serio->dev.parent = &pdev->dev; ps2if->io = serio; diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 4408245b61d2..c391700fc4ae 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c @@ -126,8 +126,8 @@ static int amba_kmi_probe(struct amba_device *dev, io->write = amba_kmi_write; io->open = amba_kmi_open; io->close = amba_kmi_close; - strlcpy(io->name, dev_name(&dev->dev), sizeof(io->name)); - strlcpy(io->phys, dev_name(&dev->dev), sizeof(io->phys)); + strscpy(io->name, dev_name(&dev->dev), sizeof(io->name)); + strscpy(io->phys, dev_name(&dev->dev), sizeof(io->phys)); io->port_data = kmi; io->dev.parent = &dev->dev; diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 1c0be299f179..ec93cb4573c3 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c @@ -159,8 +159,8 @@ static int ams_delta_serio_init(struct platform_device *pdev) serio->id.type = SERIO_8042; serio->open = ams_delta_serio_open; serio->close = ams_delta_serio_close; - strlcpy(serio->name, "AMS DELTA keyboard adapter", sizeof(serio->name)); - strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys)); + strscpy(serio->name, "AMS DELTA keyboard adapter", sizeof(serio->name)); + strscpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys)); serio->dev.parent = &pdev->dev; serio->port_data = priv; diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c index 974d7bfae0a0..9c9ce097f8bf 100644 --- a/drivers/input/serio/apbps2.c +++ b/drivers/input/serio/apbps2.c @@ -176,7 +176,7 @@ static int apbps2_of_probe(struct platform_device *ofdev) priv->io->close = apbps2_close; priv->io->write = apbps2_write; priv->io->port_data = priv; - strlcpy(priv->io->name, "APBPS2 PS/2", sizeof(priv->io->name)); + strscpy(priv->io->name, "APBPS2 PS/2", sizeof(priv->io->name)); snprintf(priv->io->phys, sizeof(priv->io->phys), "apbps2_%d", apbps2_idx++); diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index d45009d654bf..752ce60e2211 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -170,7 +170,7 @@ static int ct82c710_probe(struct platform_device *dev) ct82c710_port->open = ct82c710_open; ct82c710_port->close = ct82c710_close; ct82c710_port->write = ct82c710_write; - strlcpy(ct82c710_port->name, "C&T 82c710 mouse port", + strscpy(ct82c710_port->name, "C&T 82c710 mouse port", sizeof(ct82c710_port->name)); snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys), "isa%16llx/serio0", (unsigned long long)CT82C710_DATA); diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index da2c67cb8642..633c7de49d67 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -361,7 +361,7 @@ static int __init gscps2_probe(struct parisc_device *dev) snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s", (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); - strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); + strscpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); serio->id.type = SERIO_8042; serio->write = gscps2_write; serio->open = gscps2_open; diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c index 1a7b72a9016d..d62aefb2e245 100644 --- a/drivers/input/serio/hyperv-keyboard.c +++ b/drivers/input/serio/hyperv-keyboard.c @@ -334,9 +334,9 @@ static int hv_kbd_probe(struct hv_device *hv_dev, hv_serio->dev.parent = &hv_dev->device; hv_serio->id.type = SERIO_8042_XL; hv_serio->port_data = kbd_dev; - strlcpy(hv_serio->name, dev_name(&hv_dev->device), + strscpy(hv_serio->name, dev_name(&hv_dev->device), sizeof(hv_serio->name)); - strlcpy(hv_serio->phys, dev_name(&hv_dev->device), + strscpy(hv_serio->phys, dev_name(&hv_dev->device), sizeof(hv_serio->phys)); hv_serio->start = hv_kbd_start; diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 4fbec7bbecca..732b7a6b315d 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -1300,7 +1300,7 @@ static char i8042_pnp_aux_name[32]; static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size) { - strlcpy(dst, "PNP:", dst_size); + strscpy(dst, "PNP:", dst_size); while (id) { strlcat(dst, " ", dst_size); @@ -1320,7 +1320,7 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * if (pnp_irq_valid(dev,0)) i8042_pnp_kbd_irq = pnp_irq(dev, 0); - strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); + strscpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); if (strlen(pnp_dev_name(dev))) { strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); @@ -1347,7 +1347,7 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id * if (pnp_irq_valid(dev, 0)) i8042_pnp_aux_irq = pnp_irq(dev, 0); - strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); + strscpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); if (strlen(pnp_dev_name(dev))) { strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 3fc0a89cc785..f9486495baef 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1341,9 +1341,9 @@ static int i8042_create_kbd_port(void) serio->ps2_cmd_mutex = &i8042_mutex; serio->port_data = port; serio->dev.parent = &i8042_platform_device->dev; - strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name)); - strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys)); - strlcpy(serio->firmware_id, i8042_kbd_firmware_id, + strscpy(serio->name, "i8042 KBD port", sizeof(serio->name)); + strscpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys)); + strscpy(serio->firmware_id, i8042_kbd_firmware_id, sizeof(serio->firmware_id)); set_primary_fwnode(&serio->dev, i8042_kbd_fwnode); @@ -1371,15 +1371,15 @@ static int i8042_create_aux_port(int idx) serio->port_data = port; serio->dev.parent = &i8042_platform_device->dev; if (idx < 0) { - strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name)); - strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys)); - strlcpy(serio->firmware_id, i8042_aux_firmware_id, + strscpy(serio->name, "i8042 AUX port", sizeof(serio->name)); + strscpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys)); + strscpy(serio->firmware_id, i8042_aux_firmware_id, sizeof(serio->firmware_id)); serio->close = i8042_port_close; } else { snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx); snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1); - strlcpy(serio->firmware_id, i8042_aux_firmware_id, + strscpy(serio->firmware_id, i8042_aux_firmware_id, sizeof(serio->firmware_id)); } diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c index 59de8d9b6710..04d2db982fb8 100644 --- a/drivers/input/serio/olpc_apsp.c +++ b/drivers/input/serio/olpc_apsp.c @@ -199,8 +199,8 @@ static int olpc_apsp_probe(struct platform_device *pdev) kb_serio->close = olpc_apsp_close; kb_serio->port_data = priv; kb_serio->dev.parent = &pdev->dev; - strlcpy(kb_serio->name, "sp keyboard", sizeof(kb_serio->name)); - strlcpy(kb_serio->phys, "sp/serio0", sizeof(kb_serio->phys)); + strscpy(kb_serio->name, "sp keyboard", sizeof(kb_serio->name)); + strscpy(kb_serio->phys, "sp/serio0", sizeof(kb_serio->phys)); priv->kbio = kb_serio; serio_register_port(kb_serio); @@ -216,8 +216,8 @@ static int olpc_apsp_probe(struct platform_device *pdev) pad_serio->close = olpc_apsp_close; pad_serio->port_data = priv; pad_serio->dev.parent = &pdev->dev; - strlcpy(pad_serio->name, "sp touchpad", sizeof(pad_serio->name)); - strlcpy(pad_serio->phys, "sp/serio1", sizeof(pad_serio->phys)); + strscpy(pad_serio->name, "sp touchpad", sizeof(pad_serio->name)); + strscpy(pad_serio->phys, "sp/serio1", sizeof(pad_serio->phys)); priv->padio = pad_serio; serio_register_port(pad_serio); diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index 51b68501896c..0d54895428f5 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c @@ -169,7 +169,7 @@ static struct serio *parkbd_allocate_serio(void) if (serio) { serio->id.type = parkbd_mode; serio->write = parkbd_write; - strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name)); + strscpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name)); snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", parkbd_dev->port->name); } diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index bedf75de0a2c..05878750f2c2 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c @@ -149,8 +149,8 @@ static int pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id) serio->write = pcips2_write; serio->open = pcips2_open; serio->close = pcips2_close; - strlcpy(serio->name, pci_name(dev), sizeof(serio->name)); - strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); + strscpy(serio->name, pci_name(dev), sizeof(serio->name)); + strscpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); serio->port_data = ps2if; serio->dev.parent = &dev->dev; ps2if->io = serio; diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c index 9b02dd5dd2b9..bc1dc484389b 100644 --- a/drivers/input/serio/ps2-gpio.c +++ b/drivers/input/serio/ps2-gpio.c @@ -449,8 +449,8 @@ static int ps2_gpio_probe(struct platform_device *pdev) serio->write = drvdata->write_enable ? ps2_gpio_write : NULL; serio->port_data = drvdata; serio->dev.parent = dev; - strlcpy(serio->name, dev_name(dev), sizeof(serio->name)); - strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys)); + strscpy(serio->name, dev_name(dev), sizeof(serio->name)); + strscpy(serio->phys, dev_name(dev), sizeof(serio->phys)); drvdata->serio = serio; drvdata->dev = dev; diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c index 0071dd5ebcc2..902e81826fbf 100644 --- a/drivers/input/serio/ps2mult.c +++ b/drivers/input/serio/ps2mult.c @@ -131,7 +131,7 @@ static int ps2mult_create_port(struct ps2mult *psm, int i) if (!serio) return -ENOMEM; - strlcpy(serio->name, "TQC PS/2 Multiplexer", sizeof(serio->name)); + strscpy(serio->name, "TQC PS/2 Multiplexer", sizeof(serio->name)); snprintf(serio->phys, sizeof(serio->phys), "%s/port%d", mx_serio->phys, i); serio->id.type = SERIO_8042; diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index bd248398556a..a1c61f5de047 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -126,8 +126,8 @@ static int q40kbd_probe(struct platform_device *pdev) port->close = q40kbd_close; port->port_data = q40kbd; port->dev.parent = &pdev->dev; - strlcpy(port->name, "Q40 Kbd Port", sizeof(port->name)); - strlcpy(port->phys, "Q40", sizeof(port->phys)); + strscpy(port->name, "Q40 Kbd Port", sizeof(port->name)); + strscpy(port->phys, "Q40", sizeof(port->phys)); q40kbd_stop(); diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 37fe6a5711ea..7008bc101415 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -128,8 +128,8 @@ static int rpckbd_probe(struct platform_device *dev) serio->close = rpckbd_close; serio->dev.parent = &dev->dev; serio->port_data = rpckbd; - strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name)); - strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys)); + strscpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name)); + strscpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys)); platform_set_drvdata(dev, serio); serio_register_port(serio); diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 68fac4801e2e..2724c3aa512c 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c @@ -267,8 +267,8 @@ static int ps2_probe(struct sa1111_dev *dev) serio->write = ps2_write; serio->open = ps2_open; serio->close = ps2_close; - strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name)); - strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); + strscpy(serio->name, dev_name(&dev->dev), sizeof(serio->name)); + strscpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); serio->port_data = ps2if; serio->dev.parent = &dev->dev; ps2if->io = serio; diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 669a728095b8..7f7ef0e3a749 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -171,7 +171,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, if (!serio) return -ENOMEM; - strlcpy(serio->name, "Serial port", sizeof(serio->name)); + strscpy(serio->name, "Serial port", sizeof(serio->name)); snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty)); serio->id = serport->id; serio->id.type = SERIO_RS232; diff --git a/drivers/input/serio/sun4i-ps2.c b/drivers/input/serio/sun4i-ps2.c index f15ed3dcdb9b..eb262640192e 100644 --- a/drivers/input/serio/sun4i-ps2.c +++ b/drivers/input/serio/sun4i-ps2.c @@ -256,8 +256,8 @@ static int sun4i_ps2_probe(struct platform_device *pdev) serio->close = sun4i_ps2_close; serio->port_data = drvdata; serio->dev.parent = dev; - strlcpy(serio->name, dev_name(dev), sizeof(serio->name)); - strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys)); + strscpy(serio->name, dev_name(dev), sizeof(serio->name)); + strscpy(serio->phys, dev_name(dev), sizeof(serio->phys)); /* shutoff interrupt */ writel(0, drvdata->reg_base + PS2_REG_GCTL); diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index 56c7e471ac32..80e06727464d 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c @@ -155,7 +155,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ acecad->input = input_dev; if (dev->manufacturer) - strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name)); + strscpy(acecad->name, dev->manufacturer, sizeof(acecad->name)); if (dev->product) { if (dev->manufacturer) diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c index 6d58443bb3e9..e492a0331b24 100644 --- a/drivers/input/tablet/hanwang.c +++ b/drivers/input/tablet/hanwang.c @@ -356,7 +356,7 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id usb_make_path(dev, hanwang->phys, sizeof(hanwang->phys)); strlcat(hanwang->phys, "/input0", sizeof(hanwang->phys)); - strlcpy(hanwang->name, hanwang->features->name, sizeof(hanwang->name)); + strscpy(hanwang->name, hanwang->features->name, sizeof(hanwang->name)); input_dev->name = hanwang->name; input_dev->phys = hanwang->phys; usb_to_input_id(dev, &input_dev->id); diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c index c608ac505d1b..d836d3dcc6a2 100644 --- a/drivers/input/tablet/pegasus_notetaker.c +++ b/drivers/input/tablet/pegasus_notetaker.c @@ -319,7 +319,7 @@ static int pegasus_probe(struct usb_interface *intf, pegasus->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (dev->manufacturer) - strlcpy(pegasus->name, dev->manufacturer, + strscpy(pegasus->name, dev->manufacturer, sizeof(pegasus->name)); if (dev->product) { diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 4eedea08b0b5..ccecd1441f0b 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -2497,8 +2497,8 @@ static int mxt_vidioc_querycap(struct file *file, void *priv, { struct mxt_data *data = video_drvdata(file); - strlcpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver)); - strlcpy(cap->card, "atmel_mxt_ts touch", sizeof(cap->card)); + strscpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver)); + strscpy(cap->card, "atmel_mxt_ts touch", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "I2C:%s", dev_name(&data->client->dev)); return 0; @@ -2514,11 +2514,11 @@ static int mxt_vidioc_enum_input(struct file *file, void *priv, switch (i->index) { case MXT_V4L_INPUT_REFS: - strlcpy(i->name, "Mutual Capacitance References", + strscpy(i->name, "Mutual Capacitance References", sizeof(i->name)); break; case MXT_V4L_INPUT_DELTAS: - strlcpy(i->name, "Mutual Capacitance Deltas", sizeof(i->name)); + strscpy(i->name, "Mutual Capacitance Deltas", sizeof(i->name)); break; } diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 5fb441387fe5..9ac1378610bc 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -912,8 +912,8 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, p = strchr(rdbuf, '*'); if (p) *p++ = '\0'; - strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN); - strlcpy(fw_version, p ? p : "", EDT_NAME_LEN); + strscpy(model_name, rdbuf + 1, EDT_NAME_LEN); + strscpy(fw_version, p ? p : "", EDT_NAME_LEN); } else if (!strncasecmp(rdbuf, "EP0", 3)) { tsdata->version = EDT_M12; @@ -926,8 +926,8 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, p = strchr(rdbuf, '*'); if (p) *p++ = '\0'; - strlcpy(model_name, rdbuf, EDT_NAME_LEN); - strlcpy(fw_version, p ? p : "", EDT_NAME_LEN); + strscpy(model_name, rdbuf, EDT_NAME_LEN); + strscpy(fw_version, p ? p : "", EDT_NAME_LEN); } else { /* If it is not an EDT M06/M12 touchscreen, then the model * detection is a bit hairy. The different ft5x06 @@ -945,7 +945,7 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, if (error) return error; - strlcpy(fw_version, rdbuf, 2); + strscpy(fw_version, rdbuf, 2); error = edt_ft5x06_ts_readwrite(client, 1, "\xA8", 1, rdbuf); @@ -981,7 +981,7 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, 1, rdbuf); if (error) return error; - strlcpy(fw_version, rdbuf, 1); + strscpy(fw_version, rdbuf, 1); snprintf(model_name, EDT_NAME_LEN, "EVERVISION-FT5726NEi"); break; diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index 12f2562b0141..8ddb3f7d307a 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c @@ -939,8 +939,8 @@ static int sur40_vidioc_querycap(struct file *file, void *priv, { struct sur40_state *sur40 = video_drvdata(file); - strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver)); - strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card)); + strscpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver)); + strscpy(cap->card, DRIVER_LONG, sizeof(cap->card)); usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info)); return 0; } @@ -952,7 +952,7 @@ static int sur40_vidioc_enum_input(struct file *file, void *priv, return -EINVAL; i->type = V4L2_INPUT_TYPE_TOUCH; i->std = V4L2_STD_UNKNOWN; - strlcpy(i->name, "In-Cell Sensor", sizeof(i->name)); + strscpy(i->name, "In-Cell Sensor", sizeof(i->name)); i->capabilities = 0; return 0; } diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 3dda6eaabdab..d6d04b9f04fc 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -1708,7 +1708,7 @@ static int usbtouch_probe(struct usb_interface *intf, usbtouch->input = input_dev; if (udev->manufacturer) - strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name)); + strscpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name)); if (udev->product) { if (udev->manufacturer) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 691285ace228..928c5ee3ac36 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -625,7 +625,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) /* For backwards-compatibility we compose the basename based on * capabilities and then just append the tool type */ - strlcpy(basename, "Wacom Serial", sizeof(basename)); + strscpy(basename, "Wacom Serial", sizeof(basename)); err_pen = w8001_setup_pen(w8001, basename, sizeof(basename)); err_touch = w8001_setup_touch(w8001, basename, sizeof(basename)); @@ -635,7 +635,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) } if (!err_pen) { - strlcpy(w8001->pen_name, basename, sizeof(w8001->pen_name)); + strscpy(w8001->pen_name, basename, sizeof(w8001->pen_name)); strlcat(w8001->pen_name, " Pen", sizeof(w8001->pen_name)); input_dev_pen->name = w8001->pen_name; @@ -651,7 +651,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) } if (!err_touch) { - strlcpy(w8001->touch_name, basename, sizeof(w8001->touch_name)); + strscpy(w8001->touch_name, basename, sizeof(w8001->touch_name)); strlcat(w8001->touch_name, " Finger", sizeof(w8001->touch_name)); input_dev_touch->name = w8001->touch_name; From df805304a820ed10fc3d038dd64b85821c9ee606 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 16 Aug 2022 16:30:15 +0300 Subject: [PATCH 026/401] dt-bindings: pinctrl: samsung: stop using bindings header with constants The bindings header with pin controller register values is being deprecated and DTS already switched to a DTS-local header. Do not reference the bindings header in schema and replace the defines with raw values. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20220816133016.77553-2-krzysztof.kozlowski@linaro.org --- .../pinctrl/samsung,pinctrl-pins-cfg.yaml | 1 - .../bindings/pinctrl/samsung,pinctrl.yaml | 63 ++++++++----------- 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml index 9869d4dceddb..f796f27bf0e6 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml @@ -20,7 +20,6 @@ description: | The values used for config properties should be derived from the hardware manual and these values are programmed as-is into the pin pull up/down and driver strength register of the pin-controller. - See also include/dt-bindings/pinctrl/samsung.h with useful constants. See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for additional information and example. diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml index 3a65c66ca71d..dafa51c69c06 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml @@ -15,9 +15,6 @@ description: | This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin controller. - Pin group settings (like drive strength, pull up/down) are available as - macros in include/dt-bindings/pinctrl/samsung.h. - All the pin controller nodes should be represented in the aliases node using the following format 'pinctrl{n}' where n is a unique number for the alias. @@ -138,8 +135,6 @@ additionalProperties: false examples: - | - #include - pinctrl@7f008000 { compatible = "samsung,s3c64xx-pinctrl"; reg = <0x7f008000 0x1000>; @@ -166,8 +161,8 @@ examples: uart0-data-pins { samsung,pins = "gpa-0", "gpa-1"; - samsung,pin-function = ; - samsung,pin-pud = ; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; }; // ... @@ -175,7 +170,6 @@ examples: - | #include - #include pinctrl@11400000 { compatible = "samsung,exynos4210-pinctrl"; @@ -197,9 +191,9 @@ examples: uart0-data-pins { samsung,pins = "gpa0-0", "gpa0-1"; - samsung,pin-function = ; - samsung,pin-pud = ; - samsung,pin-drv = ; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; }; // ... @@ -207,14 +201,14 @@ examples: sleep0: sleep-state { gpa0-0-pin { samsung,pins = "gpa0-0"; - samsung,pin-con-pdn = ; - samsung,pin-pud-pdn = ; + samsung,pin-con-pdn = <2>; + samsung,pin-pud-pdn = <0>; }; gpa0-1-pin { samsung,pins = "gpa0-1"; - samsung,pin-con-pdn = ; - samsung,pin-pud-pdn = ; + samsung,pin-con-pdn = <0>; + samsung,pin-pud-pdn = <0>; }; // ... @@ -223,7 +217,6 @@ examples: - | #include - #include pinctrl@11000000 { compatible = "samsung,exynos4210-pinctrl"; @@ -272,26 +265,26 @@ examples: sd0-clk-pins { samsung,pins = "gpk0-0"; - samsung,pin-function = ; - samsung,pin-pud = ; - samsung,pin-drv = ; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; }; sd4-bus-width8-pins { part-1-pins { samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6"; - samsung,pin-function = ; - samsung,pin-pud = ; - samsung,pin-drv = ; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; }; part-2-pins { samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6"; - samsung,pin-function = ; - samsung,pin-pud = ; - samsung,pin-drv = ; + samsung,pin-function = <4>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; }; }; @@ -299,16 +292,15 @@ examples: otg-gp-pins { samsung,pins = "gpx3-3"; - samsung,pin-function = ; - samsung,pin-pud = ; - samsung,pin-drv = ; + samsung,pin-function = <1>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; samsung,pin-val = <0>; }; }; - | #include - #include pinctrl@10580000 { compatible = "samsung,exynos5433-pinctrl"; @@ -352,9 +344,9 @@ examples: initial_alive: initial-state { gpa0-0-pin { samsung,pins = "gpa0-0"; - samsung,pin-function = ; - samsung,pin-pud = ; - samsung,pin-drv = ; + samsung,pin-function = <0>; + samsung,pin-pud = <1>; + samsung,pin-drv = <0>; }; // ... @@ -363,7 +355,6 @@ examples: - | #include - #include pinctrl@114b0000 { compatible = "samsung,exynos5433-pinctrl"; @@ -384,9 +375,9 @@ examples: i2s0-bus-pins { samsung,pins = "gpz0-0", "gpz0-1", "gpz0-2", "gpz0-3", "gpz0-4", "gpz0-5", "gpz0-6"; - samsung,pin-function = ; - samsung,pin-pud = ; - samsung,pin-drv = ; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; }; // ... From 9d9292576810d0b36897718c24dfbc1a2835314b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 16 Aug 2022 16:30:16 +0300 Subject: [PATCH 027/401] dt-bindings: pinctrl: samsung: deprecate header with register constants For convenience (less code duplication, some meaning added to raw number), the pin controller pin configuration register values were defined in the bindings header. These are not some IDs or other abstraction layer but raw numbers used in the registers These constants do not fit the purpose of bindings. They do not provide any abstraction, any hardware and driver independent ID. With minor exceptions, the Linux drivers actually do not use the bindings header at all. All of the constants were moved already to headers local to DTS (residing in DTS directory) and to Samsung pinctrl driver (where applicable), so remove any references to the bindings header and add a warning tha tit is deprecated. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Chanho Park Acked-by: Rob Herring Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20220816133016.77553-3-krzysztof.kozlowski@linaro.org --- include/dt-bindings/pinctrl/samsung.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/dt-bindings/pinctrl/samsung.h b/include/dt-bindings/pinctrl/samsung.h index 950970634dfe..d1da5ff68d0c 100644 --- a/include/dt-bindings/pinctrl/samsung.h +++ b/include/dt-bindings/pinctrl/samsung.h @@ -10,6 +10,13 @@ #ifndef __DT_BINDINGS_PINCTRL_SAMSUNG_H__ #define __DT_BINDINGS_PINCTRL_SAMSUNG_H__ +/* + * These bindings are deprecated, because they do not match the actual + * concept of bindings but rather contain pure register values. + * Instead include the header in the DTS source directory. + */ +#warning "These bindings are deprecated. Instead use the header in the DTS source directory." + #define EXYNOS_PIN_PULL_NONE 0 #define EXYNOS_PIN_PULL_DOWN 1 #define EXYNOS_PIN_PULL_UP 3 From 2dce502761a2dec7dc84c03872fba5c7af110290 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 18 Aug 2022 18:11:19 +0530 Subject: [PATCH 028/401] dt-bindings: pinctrl: rockchip: Document RV1126 pinctrl Document dt-bindings for RV1126 SoC pinctrl support. Cc: linux-gpio@vger.kernel.org Cc: Linus Walleij Acked-by: Krzysztof Kozlowski Signed-off-by: Jagan Teki Link: https://lore.kernel.org/r/20220818124132.125304-7-jagan@edgeble.ai Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml index 677a285ca416..b486f41df65f 100644 --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml @@ -47,6 +47,7 @@ properties: - rockchip,rk3568-pinctrl - rockchip,rk3588-pinctrl - rockchip,rv1108-pinctrl + - rockchip,rv1126-pinctrl rockchip,grf: $ref: "/schemas/types.yaml#/definitions/phandle" From fd4ea48688c662593eb64ddf44d4a17173661672 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 18 Aug 2022 18:11:20 +0530 Subject: [PATCH 029/401] pinctrl: rockchip: Add RV1126 pinctrl support RV1126 has five GPIOs groups - GPIO0 in PD_MMU and GPIO1-4 in PD_BUS. In GPIO0, up to Lower C group GPIO0_C[3:0] is part of PMU but rest of the groups from there are part of GRF. Added pinctrl support for RV1126 and the pull, drv and schmitt calculations are inferred from [1] authored by Jianqun Xu. [1] https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/pinctrl/pinctrl-rockchip.c Cc: linux-gpio@vger.kernel.org Cc: Linus Walleij Signed-off-by: Jianqun Xu Signed-off-by: Sugar Zhang Signed-off-by: Jagan Teki Link: https://lore.kernel.org/r/20220818124132.125304-8-jagan@edgeble.ai Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 333 ++++++++++++++++++++++++++++- drivers/pinctrl/pinctrl-rockchip.h | 1 + 2 files changed, 327 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 32e41395fc76..a91061f9c2ac 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -57,6 +57,7 @@ #define IOMUX_UNROUTED BIT(3) #define IOMUX_WIDTH_3BIT BIT(4) #define IOMUX_WIDTH_2BIT BIT(5) +#define IOMUX_L_SOURCE_PMU BIT(6) #define PIN_BANK(id, pins, label) \ { \ @@ -147,6 +148,21 @@ .pull_type[3] = pull3, \ } +#define PIN_BANK_IOMUX_FLAGS_OFFSET(id, pins, label, iom0, iom1, iom2, \ + iom3, offset0, offset1, offset2, \ + offset3) \ + { \ + .bank_num = id, \ + .nr_pins = pins, \ + .name = label, \ + .iomux = { \ + { .type = iom0, .offset = offset0 }, \ + { .type = iom1, .offset = offset1 }, \ + { .type = iom2, .offset = offset2 }, \ + { .type = iom3, .offset = offset3 }, \ + }, \ + } + #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ iom2, iom3, drv0, drv1, drv2, \ drv3, offset0, offset1, \ @@ -443,6 +459,37 @@ static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = { }, }; +static struct rockchip_mux_recalced_data rv1126_mux_recalced_data[] = { + { + .num = 0, + .pin = 20, + .reg = 0x10000, + .bit = 0, + .mask = 0xf + }, + { + .num = 0, + .pin = 21, + .reg = 0x10000, + .bit = 4, + .mask = 0xf + }, + { + .num = 0, + .pin = 22, + .reg = 0x10000, + .bit = 8, + .mask = 0xf + }, + { + .num = 0, + .pin = 23, + .reg = 0x10000, + .bit = 12, + .mask = 0xf + }, +}; + static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = { { .num = 2, @@ -642,6 +689,103 @@ static struct rockchip_mux_route_data px30_mux_route_data[] = { RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */ }; +static struct rockchip_mux_route_data rv1126_mux_route_data[] = { + RK_MUXROUTE_GRF(3, RK_PD2, 1, 0x10260, WRITE_MASK_VAL(0, 0, 0)), /* I2S0_MCLK_M0 */ + RK_MUXROUTE_GRF(3, RK_PB0, 3, 0x10260, WRITE_MASK_VAL(0, 0, 1)), /* I2S0_MCLK_M1 */ + + RK_MUXROUTE_GRF(0, RK_PD4, 4, 0x10260, WRITE_MASK_VAL(3, 2, 0)), /* I2S1_MCLK_M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x10260, WRITE_MASK_VAL(3, 2, 1)), /* I2S1_MCLK_M1 */ + RK_MUXROUTE_GRF(2, RK_PC7, 6, 0x10260, WRITE_MASK_VAL(3, 2, 2)), /* I2S1_MCLK_M2 */ + + RK_MUXROUTE_GRF(1, RK_PD0, 1, 0x10260, WRITE_MASK_VAL(4, 4, 0)), /* I2S2_MCLK_M0 */ + RK_MUXROUTE_GRF(2, RK_PB3, 2, 0x10260, WRITE_MASK_VAL(4, 4, 1)), /* I2S2_MCLK_M1 */ + + RK_MUXROUTE_GRF(3, RK_PD4, 2, 0x10260, WRITE_MASK_VAL(12, 12, 0)), /* PDM_CLK0_M0 */ + RK_MUXROUTE_GRF(3, RK_PC0, 3, 0x10260, WRITE_MASK_VAL(12, 12, 1)), /* PDM_CLK0_M1 */ + + RK_MUXROUTE_GRF(3, RK_PC6, 1, 0x10264, WRITE_MASK_VAL(0, 0, 0)), /* CIF_CLKOUT_M0 */ + RK_MUXROUTE_GRF(2, RK_PD1, 3, 0x10264, WRITE_MASK_VAL(0, 0, 1)), /* CIF_CLKOUT_M1 */ + + RK_MUXROUTE_GRF(3, RK_PA4, 5, 0x10264, WRITE_MASK_VAL(5, 4, 0)), /* I2C3_SCL_M0 */ + RK_MUXROUTE_GRF(2, RK_PD4, 7, 0x10264, WRITE_MASK_VAL(5, 4, 1)), /* I2C3_SCL_M1 */ + RK_MUXROUTE_GRF(1, RK_PD6, 3, 0x10264, WRITE_MASK_VAL(5, 4, 2)), /* I2C3_SCL_M2 */ + + RK_MUXROUTE_GRF(3, RK_PA0, 7, 0x10264, WRITE_MASK_VAL(6, 6, 0)), /* I2C4_SCL_M0 */ + RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x10264, WRITE_MASK_VAL(6, 6, 1)), /* I2C4_SCL_M1 */ + + RK_MUXROUTE_GRF(2, RK_PA5, 7, 0x10264, WRITE_MASK_VAL(9, 8, 0)), /* I2C5_SCL_M0 */ + RK_MUXROUTE_GRF(3, RK_PB0, 5, 0x10264, WRITE_MASK_VAL(9, 8, 1)), /* I2C5_SCL_M1 */ + RK_MUXROUTE_GRF(1, RK_PD0, 4, 0x10264, WRITE_MASK_VAL(9, 8, 2)), /* I2C5_SCL_M2 */ + + RK_MUXROUTE_GRF(3, RK_PC0, 5, 0x10264, WRITE_MASK_VAL(11, 10, 0)), /* SPI1_CLK_M0 */ + RK_MUXROUTE_GRF(1, RK_PC6, 3, 0x10264, WRITE_MASK_VAL(11, 10, 1)), /* SPI1_CLK_M1 */ + RK_MUXROUTE_GRF(2, RK_PD5, 6, 0x10264, WRITE_MASK_VAL(11, 10, 2)), /* SPI1_CLK_M2 */ + + RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x10264, WRITE_MASK_VAL(12, 12, 0)), /* RGMII_CLK_M0 */ + RK_MUXROUTE_GRF(2, RK_PB7, 2, 0x10264, WRITE_MASK_VAL(12, 12, 1)), /* RGMII_CLK_M1 */ + + RK_MUXROUTE_GRF(3, RK_PA1, 3, 0x10264, WRITE_MASK_VAL(13, 13, 0)), /* CAN_TXD_M0 */ + RK_MUXROUTE_GRF(3, RK_PA7, 5, 0x10264, WRITE_MASK_VAL(13, 13, 1)), /* CAN_TXD_M1 */ + + RK_MUXROUTE_GRF(3, RK_PA4, 6, 0x10268, WRITE_MASK_VAL(0, 0, 0)), /* PWM8_M0 */ + RK_MUXROUTE_GRF(2, RK_PD7, 5, 0x10268, WRITE_MASK_VAL(0, 0, 1)), /* PWM8_M1 */ + + RK_MUXROUTE_GRF(3, RK_PA5, 6, 0x10268, WRITE_MASK_VAL(2, 2, 0)), /* PWM9_M0 */ + RK_MUXROUTE_GRF(2, RK_PD6, 5, 0x10268, WRITE_MASK_VAL(2, 2, 1)), /* PWM9_M1 */ + + RK_MUXROUTE_GRF(3, RK_PA6, 6, 0x10268, WRITE_MASK_VAL(4, 4, 0)), /* PWM10_M0 */ + RK_MUXROUTE_GRF(2, RK_PD5, 5, 0x10268, WRITE_MASK_VAL(4, 4, 1)), /* PWM10_M1 */ + + RK_MUXROUTE_GRF(3, RK_PA7, 6, 0x10268, WRITE_MASK_VAL(6, 6, 0)), /* PWM11_IR_M0 */ + RK_MUXROUTE_GRF(3, RK_PA1, 5, 0x10268, WRITE_MASK_VAL(6, 6, 1)), /* PWM11_IR_M1 */ + + RK_MUXROUTE_GRF(1, RK_PA5, 3, 0x10268, WRITE_MASK_VAL(8, 8, 0)), /* UART2_TX_M0 */ + RK_MUXROUTE_GRF(3, RK_PA2, 1, 0x10268, WRITE_MASK_VAL(8, 8, 1)), /* UART2_TX_M1 */ + + RK_MUXROUTE_GRF(3, RK_PC6, 3, 0x10268, WRITE_MASK_VAL(11, 10, 0)), /* UART3_TX_M0 */ + RK_MUXROUTE_GRF(1, RK_PA7, 2, 0x10268, WRITE_MASK_VAL(11, 10, 1)), /* UART3_TX_M1 */ + RK_MUXROUTE_GRF(3, RK_PA0, 4, 0x10268, WRITE_MASK_VAL(11, 10, 2)), /* UART3_TX_M2 */ + + RK_MUXROUTE_GRF(3, RK_PA4, 4, 0x10268, WRITE_MASK_VAL(13, 12, 0)), /* UART4_TX_M0 */ + RK_MUXROUTE_GRF(2, RK_PA6, 4, 0x10268, WRITE_MASK_VAL(13, 12, 1)), /* UART4_TX_M1 */ + RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x10268, WRITE_MASK_VAL(13, 12, 2)), /* UART4_TX_M2 */ + + RK_MUXROUTE_GRF(3, RK_PA6, 4, 0x10268, WRITE_MASK_VAL(15, 14, 0)), /* UART5_TX_M0 */ + RK_MUXROUTE_GRF(2, RK_PB0, 4, 0x10268, WRITE_MASK_VAL(15, 14, 1)), /* UART5_TX_M1 */ + RK_MUXROUTE_GRF(2, RK_PA0, 3, 0x10268, WRITE_MASK_VAL(15, 14, 2)), /* UART5_TX_M2 */ + + RK_MUXROUTE_PMU(0, RK_PB6, 3, 0x0114, WRITE_MASK_VAL(0, 0, 0)), /* PWM0_M0 */ + RK_MUXROUTE_PMU(2, RK_PB3, 5, 0x0114, WRITE_MASK_VAL(0, 0, 1)), /* PWM0_M1 */ + + RK_MUXROUTE_PMU(0, RK_PB7, 3, 0x0114, WRITE_MASK_VAL(2, 2, 0)), /* PWM1_M0 */ + RK_MUXROUTE_PMU(2, RK_PB2, 5, 0x0114, WRITE_MASK_VAL(2, 2, 1)), /* PWM1_M1 */ + + RK_MUXROUTE_PMU(0, RK_PC0, 3, 0x0114, WRITE_MASK_VAL(4, 4, 0)), /* PWM2_M0 */ + RK_MUXROUTE_PMU(2, RK_PB1, 5, 0x0114, WRITE_MASK_VAL(4, 4, 1)), /* PWM2_M1 */ + + RK_MUXROUTE_PMU(0, RK_PC1, 3, 0x0114, WRITE_MASK_VAL(6, 6, 0)), /* PWM3_IR_M0 */ + RK_MUXROUTE_PMU(2, RK_PB0, 5, 0x0114, WRITE_MASK_VAL(6, 6, 1)), /* PWM3_IR_M1 */ + + RK_MUXROUTE_PMU(0, RK_PC2, 3, 0x0114, WRITE_MASK_VAL(8, 8, 0)), /* PWM4_M0 */ + RK_MUXROUTE_PMU(2, RK_PA7, 5, 0x0114, WRITE_MASK_VAL(8, 8, 1)), /* PWM4_M1 */ + + RK_MUXROUTE_PMU(0, RK_PC3, 3, 0x0114, WRITE_MASK_VAL(10, 10, 0)), /* PWM5_M0 */ + RK_MUXROUTE_PMU(2, RK_PA6, 5, 0x0114, WRITE_MASK_VAL(10, 10, 1)), /* PWM5_M1 */ + + RK_MUXROUTE_PMU(0, RK_PB2, 3, 0x0114, WRITE_MASK_VAL(12, 12, 0)), /* PWM6_M0 */ + RK_MUXROUTE_PMU(2, RK_PD4, 5, 0x0114, WRITE_MASK_VAL(12, 12, 1)), /* PWM6_M1 */ + + RK_MUXROUTE_PMU(0, RK_PB1, 3, 0x0114, WRITE_MASK_VAL(14, 14, 0)), /* PWM7_IR_M0 */ + RK_MUXROUTE_PMU(3, RK_PA0, 5, 0x0114, WRITE_MASK_VAL(14, 14, 1)), /* PWM7_IR_M1 */ + + RK_MUXROUTE_PMU(0, RK_PB0, 1, 0x0118, WRITE_MASK_VAL(1, 0, 0)), /* SPI0_CLK_M0 */ + RK_MUXROUTE_PMU(2, RK_PA1, 1, 0x0118, WRITE_MASK_VAL(1, 0, 1)), /* SPI0_CLK_M1 */ + RK_MUXROUTE_PMU(2, RK_PB2, 6, 0x0118, WRITE_MASK_VAL(1, 0, 2)), /* SPI0_CLK_M2 */ + + RK_MUXROUTE_PMU(0, RK_PB6, 2, 0x0118, WRITE_MASK_VAL(2, 2, 0)), /* UART1_TX_M0 */ + RK_MUXROUTE_PMU(1, RK_PD0, 5, 0x0118, WRITE_MASK_VAL(2, 2, 1)), /* UART1_TX_M1 */ +}; + static struct rockchip_mux_route_data rk3128_mux_route_data[] = { RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */ RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */ @@ -877,8 +1021,12 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) return RK_FUNC_GPIO; - regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) - ? info->regmap_pmu : info->regmap_base; + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + regmap = info->regmap_pmu; + else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU) + regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base; + else + regmap = info->regmap_base; /* get basic quadrupel of mux registers and the correct reg inside */ mux_type = bank->iomux[iomux_num].type; @@ -987,8 +1135,12 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); - regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) - ? info->regmap_pmu : info->regmap_base; + if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + regmap = info->regmap_pmu; + else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU) + regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base; + else + regmap = info->regmap_base; /* get basic quadrupel of mux registers and the correct reg inside */ mux_type = bank->iomux[iomux_num].type; @@ -1268,6 +1420,119 @@ static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +#define RV1126_PULL_PMU_OFFSET 0x40 +#define RV1126_PULL_GRF_GPIO1A0_OFFSET 0x10108 +#define RV1126_PULL_PINS_PER_REG 8 +#define RV1126_PULL_BITS_PER_PIN 2 +#define RV1126_PULL_BANK_STRIDE 16 +#define RV1126_GPIO_C4_D7(p) (p >= 20 && p <= 31) /* GPIO0_C4 ~ GPIO0_D7 */ + +static int rv1126_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 24 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + if (RV1126_GPIO_C4_D7(pin_num)) { + *regmap = info->regmap_base; + *reg = RV1126_PULL_GRF_GPIO1A0_OFFSET; + *reg -= (((31 - pin_num) / RV1126_PULL_PINS_PER_REG + 1) * 4); + *bit = pin_num % RV1126_PULL_PINS_PER_REG; + *bit *= RV1126_PULL_BITS_PER_PIN; + return 0; + } + *regmap = info->regmap_pmu; + *reg = RV1126_PULL_PMU_OFFSET; + } else { + *reg = RV1126_PULL_GRF_GPIO1A0_OFFSET; + *regmap = info->regmap_base; + *reg += (bank->bank_num - 1) * RV1126_PULL_BANK_STRIDE; + } + + *reg += ((pin_num / RV1126_PULL_PINS_PER_REG) * 4); + *bit = (pin_num % RV1126_PULL_PINS_PER_REG); + *bit *= RV1126_PULL_BITS_PER_PIN; + + return 0; +} + +#define RV1126_DRV_PMU_OFFSET 0x20 +#define RV1126_DRV_GRF_GPIO1A0_OFFSET 0x10090 +#define RV1126_DRV_BITS_PER_PIN 4 +#define RV1126_DRV_PINS_PER_REG 4 +#define RV1126_DRV_BANK_STRIDE 32 + +static int rv1126_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 24 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + if (RV1126_GPIO_C4_D7(pin_num)) { + *regmap = info->regmap_base; + *reg = RV1126_DRV_GRF_GPIO1A0_OFFSET; + *reg -= (((31 - pin_num) / RV1126_DRV_PINS_PER_REG + 1) * 4); + *reg -= 0x4; + *bit = pin_num % RV1126_DRV_PINS_PER_REG; + *bit *= RV1126_DRV_BITS_PER_PIN; + return 0; + } + *regmap = info->regmap_pmu; + *reg = RV1126_DRV_PMU_OFFSET; + } else { + *regmap = info->regmap_base; + *reg = RV1126_DRV_GRF_GPIO1A0_OFFSET; + *reg += (bank->bank_num - 1) * RV1126_DRV_BANK_STRIDE; + } + + *reg += ((pin_num / RV1126_DRV_PINS_PER_REG) * 4); + *bit = pin_num % RV1126_DRV_PINS_PER_REG; + *bit *= RV1126_DRV_BITS_PER_PIN; + + return 0; +} + +#define RV1126_SCHMITT_PMU_OFFSET 0x60 +#define RV1126_SCHMITT_GRF_GPIO1A0_OFFSET 0x10188 +#define RV1126_SCHMITT_BANK_STRIDE 16 +#define RV1126_SCHMITT_PINS_PER_GRF_REG 8 +#define RV1126_SCHMITT_PINS_PER_PMU_REG 8 + +static int rv1126_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + int pins_per_reg; + + if (bank->bank_num == 0) { + if (RV1126_GPIO_C4_D7(pin_num)) { + *regmap = info->regmap_base; + *reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET; + *reg -= (((31 - pin_num) / RV1126_SCHMITT_PINS_PER_GRF_REG + 1) * 4); + *bit = pin_num % RV1126_SCHMITT_PINS_PER_GRF_REG; + return 0; + } + *regmap = info->regmap_pmu; + *reg = RV1126_SCHMITT_PMU_OFFSET; + pins_per_reg = RV1126_SCHMITT_PINS_PER_PMU_REG; + } else { + *regmap = info->regmap_base; + *reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET; + pins_per_reg = RV1126_SCHMITT_PINS_PER_GRF_REG; + *reg += (bank->bank_num - 1) * RV1126_SCHMITT_BANK_STRIDE; + } + *reg += ((pin_num / pins_per_reg) * 4); + *bit = pin_num % pins_per_reg; + + return 0; +} + #define RK3308_SCHMITT_PINS_PER_REG 8 #define RK3308_SCHMITT_BANK_STRIDE 16 #define RK3308_SCHMITT_GRF_OFFSET 0x1a0 @@ -1998,6 +2263,12 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, goto config; } + if (ctrl->type == RV1126) { + rmask_bits = RV1126_DRV_BITS_PER_PIN; + ret = strength; + goto config; + } + ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { if (rockchip_perpin_drv_list[drv_type][i] == strength) { @@ -2168,6 +2439,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, break; case PX30: case RV1108: + case RV1126: case RK3188: case RK3288: case RK3308: @@ -2416,6 +2688,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, return pull ? false : true; case PX30: case RV1108: + case RV1126: case RK3188: case RK3288: case RK3308: @@ -2889,12 +3162,14 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( /* preset iomux offset value, set new start value */ if (iom->offset >= 0) { - if (iom->type & IOMUX_SOURCE_PMU) + if ((iom->type & IOMUX_SOURCE_PMU) || + (iom->type & IOMUX_L_SOURCE_PMU)) pmu_offs = iom->offset; else grf_offs = iom->offset; } else { /* set current iomux offset */ - iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? + iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || + (iom->type & IOMUX_L_SOURCE_PMU)) ? pmu_offs : grf_offs; } @@ -2919,7 +3194,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( inc = (iom->type & (IOMUX_WIDTH_4BIT | IOMUX_WIDTH_3BIT | IOMUX_WIDTH_2BIT)) ? 8 : 4; - if (iom->type & IOMUX_SOURCE_PMU) + if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU)) pmu_offs += inc; else grf_offs += inc; @@ -3178,6 +3453,48 @@ static struct rockchip_pin_ctrl rv1108_pin_ctrl = { .schmitt_calc_reg = rv1108_calc_schmitt_reg_and_bit, }; +static struct rockchip_pin_bank rv1126_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", + IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, + IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, + IOMUX_WIDTH_4BIT | IOMUX_L_SOURCE_PMU, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0x10010, 0x10018, 0x10020, 0x10028), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(4, 2, "gpio4", + IOMUX_WIDTH_4BIT, 0, 0, 0), +}; + +static struct rockchip_pin_ctrl rv1126_pin_ctrl = { + .pin_banks = rv1126_pin_banks, + .nr_banks = ARRAY_SIZE(rv1126_pin_banks), + .label = "RV1126-GPIO", + .type = RV1126, + .grf_mux_offset = 0x10004, /* mux offset from GPIO0_D0 */ + .pmu_mux_offset = 0x0, + .iomux_routes = rv1126_mux_route_data, + .niomux_routes = ARRAY_SIZE(rv1126_mux_route_data), + .iomux_recalced = rv1126_mux_recalced_data, + .niomux_recalced = ARRAY_SIZE(rv1126_mux_recalced_data), + .pull_calc_reg = rv1126_calc_pull_reg_and_bit, + .drv_calc_reg = rv1126_calc_drv_reg_and_bit, + .schmitt_calc_reg = rv1126_calc_schmitt_reg_and_bit, +}; + static struct rockchip_pin_bank rk2928_pin_banks[] = { PIN_BANK(0, 32, "gpio0"), PIN_BANK(1, 32, "gpio1"), @@ -3568,6 +3885,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { .data = &px30_pin_ctrl }, { .compatible = "rockchip,rv1108-pinctrl", .data = &rv1108_pin_ctrl }, + { .compatible = "rockchip,rv1126-pinctrl", + .data = &rv1126_pin_ctrl }, { .compatible = "rockchip,rk2928-pinctrl", .data = &rk2928_pin_ctrl }, { .compatible = "rockchip,rk3036-pinctrl", diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h index ec46f8815ac9..4759f336941e 100644 --- a/drivers/pinctrl/pinctrl-rockchip.h +++ b/drivers/pinctrl/pinctrl-rockchip.h @@ -186,6 +186,7 @@ enum rockchip_pinctrl_type { PX30, RV1108, + RV1126, RK2928, RK3066B, RK3128, From 0ca6e30e4dd1d97416a7febcc8bf06f72e19f063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 5 Aug 2022 14:21:59 +0200 Subject: [PATCH 030/401] pinctrl: armada-37xx: Add missing GPIO-only pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gpio1_5 and gpio2_2 are GPIO-only pins. Add them into MPP groups table so they are properly exported as valid pin numbers. Fixes: 87466ccd9401 ("pinctrl: armada-37xx: Add pin controller support for Armada 37xx") Signed-off-by: Pali Rohár Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20220805122202.23174-1-pali@kernel.org Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index bcde042d29dc..2a9425847a92 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -122,6 +122,16 @@ struct armada_37xx_pinctrl { .funcs = {_func1, _func2} \ } +#define PIN_GRP_GPIO_0(_name, _start, _nr) \ + { \ + .name = _name, \ + .start_pin = _start, \ + .npins = _nr, \ + .reg_mask = 0, \ + .val = {0}, \ + .funcs = {"gpio"} \ + } + #define PIN_GRP_GPIO(_name, _start, _nr, _mask, _func1) \ { \ .name = _name, \ @@ -179,6 +189,7 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { "pwm", "led"), PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"), PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"), + PIN_GRP_GPIO_0("gpio1_5", 5, 1), PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"), PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"), PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"), @@ -195,6 +206,7 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"), PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"), + PIN_GRP_GPIO_0("gpio2_2", 2, 1), PIN_GRP_GPIO("sdio_sb", 24, 6, BIT(2), "sdio"), PIN_GRP_GPIO("rgmii", 6, 12, BIT(3), "mii"), PIN_GRP_GPIO("smi", 18, 2, BIT(4), "smi"), From 2fa9933d685ee9bcab056c81ef5f7fa242ba90e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 5 Aug 2022 14:22:00 +0200 Subject: [PATCH 031/401] pinctrl: armada-37xx: Fix definitions for MPP pins 20-22 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All 3 MPP pins (20, 21 and 22) can be configured individually and also can be configured to GPIO functions. Fix definitions for these MPP pins in existing pin groups. After this change GPIO function can be enabled just for one of these 3 pins. Fixes: 87466ccd9401 ("pinctrl: armada-37xx: Add pin controller support for Armada 37xx") Signed-off-by: Pali Rohár Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20220805122202.23174-2-pali@kernel.org Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 2a9425847a92..3a39c670615f 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -213,9 +213,11 @@ static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { PIN_GRP_GPIO("pcie1", 3, 1, BIT(5), "pcie"), /* this actually controls "pcie1_reset" */ PIN_GRP_GPIO("pcie1_clkreq", 4, 1, BIT(9), "pcie"), PIN_GRP_GPIO("pcie1_wakeup", 5, 1, BIT(10), "pcie"), - PIN_GRP_GPIO("ptp", 20, 3, BIT(11) | BIT(12) | BIT(13), "ptp"), - PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"), - PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"), + PIN_GRP_GPIO("ptp", 20, 1, BIT(11), "ptp"), + PIN_GRP_GPIO_3("ptp_clk", 21, 1, BIT(6) | BIT(12), 0, BIT(6), BIT(12), + "ptp", "mii"), + PIN_GRP_GPIO_3("ptp_trig", 22, 1, BIT(7) | BIT(13), 0, BIT(7), BIT(13), + "ptp", "mii"), PIN_GRP_GPIO_3("mii_col", 23, 1, BIT(8) | BIT(14), 0, BIT(8), BIT(14), "mii", "mii_err"), }; From 6b262b32faf0abf74062e2e2b72cbbea4572b9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 5 Aug 2022 14:22:01 +0200 Subject: [PATCH 032/401] pinctrl: armada-37xx: Checks for errors in gpio_request_enable callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now when all MPP pins are properly defined and every MPP pin has GPIO function, always checks for errors in armada_37xx_gpio_request_enable() function when calling armada_37xx_pmx_set_by_name(). Function armada_37xx_pmx_set_by_name() should not return "not supported" error anymore for any GPIO pin when requesting GPIO mode. Fixes: 87466ccd9401 ("pinctrl: armada-37xx: Add pin controller support for Armada 37xx") Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20220805122202.23174-3-pali@kernel.org Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 3a39c670615f..7f5665e598bf 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -500,11 +500,15 @@ static int armada_37xx_gpio_request_enable(struct pinctrl_dev *pctldev, struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct armada_37xx_pin_group *group; int grp = 0; + int ret; dev_dbg(info->dev, "requesting gpio %d\n", offset); - while ((group = armada_37xx_find_next_grp_by_pin(info, offset, &grp))) - armada_37xx_pmx_set_by_name(pctldev, "gpio", group); + while ((group = armada_37xx_find_next_grp_by_pin(info, offset, &grp))) { + ret = armada_37xx_pmx_set_by_name(pctldev, "gpio", group); + if (ret) + return ret; + } return 0; } From 599e465d11a5621063bc5db2d222081716dc3403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 5 Aug 2022 14:22:02 +0200 Subject: [PATCH 033/401] pinctrl: armada-37xx: Remove unused macro PIN_GRP() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Macro PIN_GRP() is not used, remove it. Signed-off-by: Pali Rohár Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20220805122202.23174-4-pali@kernel.org Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 7f5665e598bf..261b46841b9f 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -112,16 +112,6 @@ struct armada_37xx_pinctrl { struct armada_37xx_pm_state pm; }; -#define PIN_GRP(_name, _start, _nr, _mask, _func1, _func2) \ - { \ - .name = _name, \ - .start_pin = _start, \ - .npins = _nr, \ - .reg_mask = _mask, \ - .val = {0, _mask}, \ - .funcs = {_func1, _func2} \ - } - #define PIN_GRP_GPIO_0(_name, _start, _nr) \ { \ .name = _name, \ From 27586b851bae62296b77687a58a8c92ab84d5274 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 10 Aug 2022 10:16:34 -0600 Subject: [PATCH 034/401] dt-bindings: pinctrl: aspeed: Add missing properties to examples The aspeed pinctrl parent node (SCU) in the examples is missing various properties. Add the properties in preparation for the SCU schema. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220810161635.73936-2-robh@kernel.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml | 6 ++++++ .../devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml | 4 ++++ .../devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml index d3a8911728d0..f4f1ee6b116e 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml @@ -63,6 +63,12 @@ examples: syscon: scu@1e6e2000 { compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd"; reg = <0x1e6e2000 0x1a8>; + #clock-cells = <1>; + #reset-cells = <1>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1e6e2000 0x1000>; pinctrl: pinctrl { compatible = "aspeed,ast2400-pinctrl"; diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml index 5d2c1b1fb7fd..8168f0088471 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml @@ -82,6 +82,10 @@ examples: #clock-cells = <1>; #reset-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1e6e2000 0x1000>; + pinctrl: pinctrl { compatible = "aspeed,ast2500-pinctrl"; aspeed,external-nodes = <&gfx>, <&lhc>; diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml index e92686d2f062..62424c42c981 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml @@ -96,6 +96,12 @@ examples: syscon: scu@1e6e2000 { compatible = "aspeed,ast2600-scu", "syscon", "simple-mfd"; reg = <0x1e6e2000 0xf6c>; + #clock-cells = <1>; + #reset-cells = <1>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1e6e2000 0x1000>; pinctrl: pinctrl { compatible = "aspeed,ast2600-pinctrl"; From a9da7251ac8bcc2f2358513868f1903ac2809b3d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 22 Aug 2022 17:14:58 -0700 Subject: [PATCH 035/401] Input: gameport - move from strlcpy with unused retval to strscpy Follow the advice of the below link and prefer 'strscpy' in this subsystem. Conversion is 1:1 because the return value is not used. Generated by a coccinelle script. Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20220818210156.8143-1-wsa+renesas@sang-engineering.com Signed-off-by: Dmitry Torokhov --- include/linux/gameport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 69081d899492..8c2f00018e89 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -110,7 +110,7 @@ static inline void gameport_free_port(struct gameport *gameport) static inline void gameport_set_name(struct gameport *gameport, const char *name) { - strlcpy(gameport->name, name, sizeof(gameport->name)); + strscpy(gameport->name, name, sizeof(gameport->name)); } /* From 6611656736f8f2b94767f5999e78400370d84480 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 Jul 2022 09:13:41 +0200 Subject: [PATCH 036/401] dt-bindings: PCI: qcom: Enumerate platforms with single msi interrupt Explicitly enumerate the older platforms that have a single msi host interrupt. This allows for adding further platforms with, for example, four msi interrupts without resorting to nested conditionals. Drop the redundant comment about older chipsets instead of moving it. Link: https://lore.kernel.org/r/20220714071348.6792-2-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Manivannan Sadhasivam Acked-by: Krzysztof Kozlowski Acked-by: Stanimir Varbanov --- .../devicetree/bindings/pci/qcom,pcie.yaml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml index 7d29e2a45183..ea388113f04a 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml @@ -625,7 +625,6 @@ allOf: - reset-names # Newer chipsets support either 1 or 8 MSI vectors - # On older chipsets it's always 1 MSI vector - if: properties: compatible: @@ -660,7 +659,21 @@ allOf: - const: msi5 - const: msi6 - const: msi7 - else: + + - if: + properties: + compatible: + contains: + enum: + - qcom,pcie-apq8064 + - qcom,pcie-apq8084 + - qcom,pcie-ipq4019 + - qcom,pcie-ipq6018 + - qcom,pcie-ipq8064 + - qcom,pcie-ipq8064-v2 + - qcom,pcie-ipq8074 + - qcom,pcie-qcs404 + then: properties: interrupts: maxItems: 1 From 76d777ae045e345ccfbf2d7c873674de09a8a041 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 Jul 2022 09:13:42 +0200 Subject: [PATCH 037/401] dt-bindings: PCI: qcom: Add SC8280XP to binding Add the SC8280XP platform to the binding. SC8280XP use four host interrupts for MSI routing so remove the obsolete comment referring to newer chipsets supporting one or eight interrupts (e.g. for backwards compatibility). Link: https://lore.kernel.org/r/20220714071348.6792-3-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Acked-by: Krzysztof Kozlowski Acked-by: Stanimir Varbanov --- .../devicetree/bindings/pci/qcom,pcie.yaml | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml index ea388113f04a..577d166a7476 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml @@ -27,6 +27,7 @@ properties: - qcom,pcie-qcs404 - qcom,pcie-sc7280 - qcom,pcie-sc8180x + - qcom,pcie-sc8280xp - qcom,pcie-sdm845 - qcom,pcie-sm8150 - qcom,pcie-sm8250 @@ -181,6 +182,7 @@ allOf: enum: - qcom,pcie-sc7280 - qcom,pcie-sc8180x + - qcom,pcie-sc8280xp - qcom,pcie-sm8250 - qcom,pcie-sm8450-pcie0 - qcom,pcie-sm8450-pcie1 @@ -596,6 +598,35 @@ allOf: items: - const: pci # PCIe core reset + - if: + properties: + compatible: + contains: + enum: + - qcom,pcie-sc8280xp + then: + properties: + clocks: + minItems: 8 + maxItems: 9 + clock-names: + minItems: 8 + items: + - const: aux # Auxiliary clock + - const: cfg # Configuration clock + - const: bus_master # Master AXI clock + - const: bus_slave # Slave AXI clock + - const: slave_q2a # Slave Q2A clock + - const: ddrss_sf_tbu # PCIe SF TBU clock + - const: noc_aggr_4 # NoC aggregate 4 clock + - const: noc_aggr_south_sf # NoC aggregate South SF clock + - const: cnoc_qx # Configuration NoC QX clock + resets: + maxItems: 1 + reset-names: + items: + - const: pci # PCIe core reset + - if: not: properties: @@ -624,7 +655,6 @@ allOf: - resets - reset-names - # Newer chipsets support either 1 or 8 MSI vectors - if: properties: compatible: @@ -660,6 +690,24 @@ allOf: - const: msi6 - const: msi7 + - if: + properties: + compatible: + contains: + enum: + - qcom,pcie-sc8280xp + then: + properties: + interrupts: + minItems: 4 + maxItems: 4 + interrupt-names: + items: + - const: msi0 + - const: msi1 + - const: msi2 + - const: msi3 + - if: properties: compatible: From 76c4207f4085f00d03c96c72c528ee0810692f57 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 Jul 2022 09:13:43 +0200 Subject: [PATCH 038/401] dt-bindings: PCI: qcom: Add SA8540P to binding SA8540P is a new platform related to SC8280XP but which uses a single host interrupt for MSI routing. Link: https://lore.kernel.org/r/20220714071348.6792-4-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Brian Masney Acked-by: Krzysztof Kozlowski Acked-by: Stanimir Varbanov --- Documentation/devicetree/bindings/pci/qcom,pcie.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml index 577d166a7476..22a2aac4c23f 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml @@ -25,6 +25,7 @@ properties: - qcom,pcie-ipq4019 - qcom,pcie-ipq8074 - qcom,pcie-qcs404 + - qcom,pcie-sa8540p - qcom,pcie-sc7280 - qcom,pcie-sc8180x - qcom,pcie-sc8280xp @@ -603,6 +604,7 @@ allOf: compatible: contains: enum: + - qcom,pcie-sa8540p - qcom,pcie-sc8280xp then: properties: @@ -721,6 +723,7 @@ allOf: - qcom,pcie-ipq8064-v2 - qcom,pcie-ipq8074 - qcom,pcie-qcs404 + - qcom,pcie-sa8540p then: properties: interrupts: From 70574511f3fc2eea360043aaf7fcbbe4b1ea22b9 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 Jul 2022 09:13:44 +0200 Subject: [PATCH 039/401] PCI: qcom: Add support for SC8280XP The SC8280XP platform has seven PCIe controllers: two used with USB4, two 4-lane, two 2-lane and one 1-lane. Add a new "qcom,pcie-sc8280xp" compatible string and reuse the 1.9.0 ops. Note that the SC8280XP controllers need two or three interconnect clocks to be enabled. Model these as optional clocks to avoid encoding devicetree data in the PCIe driver. Note that the same could be done for the SM8450 interconnect clocks and possibly also for the TBU clocks. Link: https://lore.kernel.org/r/20220714071348.6792-5-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Manivannan Sadhasivam Acked-by: Stanimir Varbanov --- drivers/pci/controller/dwc/pcie-qcom.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 66886dc6e777..11841f2fae9b 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -180,7 +180,7 @@ struct qcom_pcie_resources_2_3_3 { /* 6 clocks typically, 7 for sm8250 */ struct qcom_pcie_resources_2_7_0 { - struct clk_bulk_data clks[9]; + struct clk_bulk_data clks[12]; int num_clks; struct regulator_bulk_data supplies[2]; struct reset_control *pci_reset; @@ -1175,6 +1175,7 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie) struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0; struct dw_pcie *pci = pcie->pci; struct device *dev = pci->dev; + unsigned int num_clks, num_opt_clks; unsigned int idx; int ret; @@ -1204,9 +1205,20 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie) if (pcie->cfg->has_aggre1_clk) res->clks[idx++].id = "aggre1"; + num_clks = idx; + + ret = devm_clk_bulk_get(dev, num_clks, res->clks); + if (ret < 0) + return ret; + + res->clks[idx++].id = "noc_aggr_4"; + res->clks[idx++].id = "noc_aggr_south_sf"; + res->clks[idx++].id = "cnoc_qx"; + + num_opt_clks = idx - num_clks; res->num_clks = idx; - ret = devm_clk_bulk_get(dev, res->num_clks, res->clks); + ret = devm_clk_bulk_get_optional(dev, num_opt_clks, res->clks + num_clks); if (ret < 0) return ret; @@ -1621,6 +1633,11 @@ static const struct qcom_pcie_cfg ipq4019_cfg = { .ops = &ops_2_4_0, }; +static const struct qcom_pcie_cfg sc8280xp_cfg = { + .ops = &ops_1_9_0, + .has_ddrss_sf_tbu_clk = true, +}; + static const struct qcom_pcie_cfg sdm845_cfg = { .ops = &ops_2_7_0, .has_tbu_clk = true, @@ -1773,6 +1790,7 @@ static const struct of_device_id qcom_pcie_match[] = { { .compatible = "qcom,pcie-sm8150", .data = &sm8150_cfg }, { .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg }, { .compatible = "qcom,pcie-sc8180x", .data = &sc8180x_cfg }, + { .compatible = "qcom,pcie-sc8280xp", .data = &sc8280xp_cfg }, { .compatible = "qcom,pcie-sm8450-pcie0", .data = &sm8450_pcie0_cfg }, { .compatible = "qcom,pcie-sm8450-pcie1", .data = &sm8450_pcie1_cfg }, { .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg }, From c64f56d0857a28ad9f4e5b6e68877a6b05660073 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 Jul 2022 09:13:45 +0200 Subject: [PATCH 040/401] PCI: qcom: Add support for SA8540P The SA8540P platform has five PCIe controllers: two 4-lane, two 2-lane and one 1-lane. Add a new "qcom,pcie-sa8540p" compatible string and reuse the 1.9.0 ops. Note that like for SC8280XP, the SA8540P controllers need two or three interconnect clocks to be enabled. Link: https://lore.kernel.org/r/20220714071348.6792-6-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring Reviewed-by: Manivannan Sadhasivam Reviewed-by: Brian Masney Acked-by: Stanimir Varbanov --- drivers/pci/controller/dwc/pcie-qcom.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 11841f2fae9b..260961f5808e 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1633,6 +1633,11 @@ static const struct qcom_pcie_cfg ipq4019_cfg = { .ops = &ops_2_4_0, }; +static const struct qcom_pcie_cfg sa8540p_cfg = { + .ops = &ops_1_9_0, + .has_ddrss_sf_tbu_clk = true, +}; + static const struct qcom_pcie_cfg sc8280xp_cfg = { .ops = &ops_1_9_0, .has_ddrss_sf_tbu_clk = true, @@ -1786,6 +1791,7 @@ static const struct of_device_id qcom_pcie_match[] = { { .compatible = "qcom,pcie-ipq8074", .data = &ipq8074_cfg }, { .compatible = "qcom,pcie-ipq4019", .data = &ipq4019_cfg }, { .compatible = "qcom,pcie-qcs404", .data = &ipq4019_cfg }, + { .compatible = "qcom,pcie-sa8540p", .data = &sa8540p_cfg }, { .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg }, { .compatible = "qcom,pcie-sm8150", .data = &sm8150_cfg }, { .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg }, From 014aa3518a5826b88a601f5de867551db5c73855 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 Jul 2022 09:13:46 +0200 Subject: [PATCH 041/401] PCI: qcom: Make all optional clocks optional The kernel is not a devicetree validator and does not need to re-encode information which is already available in the devicetree. This is specifically true for the optional PCIe clocks, some of which are really interconnect clocks. Treat also the 2.7.0 optional clocks as truly optional instead of maintaining a list of clocks per compatible (including two compatible strings for the two identical controllers on sm8450) just to validate the devicetree. Link: https://lore.kernel.org/r/20220714071348.6792-7-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring Reviewed-by: Manivannan Sadhasivam Reviewed-by: Dmitry Baryshkov Reviewed-by: Brian Masney Acked-by: Stanimir Varbanov --- drivers/pci/controller/dwc/pcie-qcom.c | 28 ++++---------------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 260961f5808e..e7e3aa15d292 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -215,10 +215,6 @@ struct qcom_pcie_ops { struct qcom_pcie_cfg { const struct qcom_pcie_ops *ops; - unsigned int has_tbu_clk:1; - unsigned int has_ddrss_sf_tbu_clk:1; - unsigned int has_aggre0_clk:1; - unsigned int has_aggre1_clk:1; }; struct qcom_pcie { @@ -1196,14 +1192,6 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie) res->clks[idx++].id = "bus_master"; res->clks[idx++].id = "bus_slave"; res->clks[idx++].id = "slave_q2a"; - if (pcie->cfg->has_tbu_clk) - res->clks[idx++].id = "tbu"; - if (pcie->cfg->has_ddrss_sf_tbu_clk) - res->clks[idx++].id = "ddrss_sf_tbu"; - if (pcie->cfg->has_aggre0_clk) - res->clks[idx++].id = "aggre0"; - if (pcie->cfg->has_aggre1_clk) - res->clks[idx++].id = "aggre1"; num_clks = idx; @@ -1211,6 +1199,10 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie) if (ret < 0) return ret; + res->clks[idx++].id = "tbu"; + res->clks[idx++].id = "ddrss_sf_tbu"; + res->clks[idx++].id = "aggre0"; + res->clks[idx++].id = "aggre1"; res->clks[idx++].id = "noc_aggr_4"; res->clks[idx++].id = "noc_aggr_south_sf"; res->clks[idx++].id = "cnoc_qx"; @@ -1635,17 +1627,14 @@ static const struct qcom_pcie_cfg ipq4019_cfg = { static const struct qcom_pcie_cfg sa8540p_cfg = { .ops = &ops_1_9_0, - .has_ddrss_sf_tbu_clk = true, }; static const struct qcom_pcie_cfg sc8280xp_cfg = { .ops = &ops_1_9_0, - .has_ddrss_sf_tbu_clk = true, }; static const struct qcom_pcie_cfg sdm845_cfg = { .ops = &ops_2_7_0, - .has_tbu_clk = true, }; static const struct qcom_pcie_cfg sm8150_cfg = { @@ -1657,31 +1646,22 @@ static const struct qcom_pcie_cfg sm8150_cfg = { static const struct qcom_pcie_cfg sm8250_cfg = { .ops = &ops_1_9_0, - .has_tbu_clk = true, - .has_ddrss_sf_tbu_clk = true, }; static const struct qcom_pcie_cfg sm8450_pcie0_cfg = { .ops = &ops_1_9_0, - .has_ddrss_sf_tbu_clk = true, - .has_aggre0_clk = true, - .has_aggre1_clk = true, }; static const struct qcom_pcie_cfg sm8450_pcie1_cfg = { .ops = &ops_1_9_0, - .has_ddrss_sf_tbu_clk = true, - .has_aggre1_clk = true, }; static const struct qcom_pcie_cfg sc7280_cfg = { .ops = &ops_1_9_0, - .has_tbu_clk = true, }; static const struct qcom_pcie_cfg sc8180x_cfg = { .ops = &ops_1_9_0, - .has_tbu_clk = true, }; static const struct qcom_pcie_cfg ipq6018_cfg = { From 223117350636e20a86fa540e9b53804194939057 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 Jul 2022 09:13:47 +0200 Subject: [PATCH 042/401] PCI: qcom: Clean up IP configurations The various IP versions have different configurations that are encoded in separate sets of operation callbacks. Currently, there is no need for also maintaining corresponding sets of data parameters, but it is conceivable that these may again be found useful (e.g. to implement minor variations of the operation callbacks). Rename the default configuration structures after the IP version they apply to so that they can more easily be reused by different SoCs. Note that SoC specific configurations can be added later if need arises (e.g. cfg_sc8280xp). Link: https://lore.kernel.org/r/20220714071348.6792-8-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring Reviewed-by: Manivannan Sadhasivam Reviewed-by: Dmitry Baryshkov Reviewed-by: Brian Masney Acked-by: Stanimir Varbanov --- drivers/pci/controller/dwc/pcie-qcom.c | 89 +++++++++----------------- 1 file changed, 29 insertions(+), 60 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index e7e3aa15d292..ade3704ba6ea 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1605,66 +1605,35 @@ static const struct qcom_pcie_ops ops_2_9_0 = { .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, }; -static const struct qcom_pcie_cfg apq8084_cfg = { +static const struct qcom_pcie_cfg cfg_1_0_0 = { .ops = &ops_1_0_0, }; -static const struct qcom_pcie_cfg ipq8064_cfg = { +static const struct qcom_pcie_cfg cfg_1_9_0 = { + .ops = &ops_1_9_0, +}; + +static const struct qcom_pcie_cfg cfg_2_1_0 = { .ops = &ops_2_1_0, }; -static const struct qcom_pcie_cfg msm8996_cfg = { +static const struct qcom_pcie_cfg cfg_2_3_2 = { .ops = &ops_2_3_2, }; -static const struct qcom_pcie_cfg ipq8074_cfg = { +static const struct qcom_pcie_cfg cfg_2_3_3 = { .ops = &ops_2_3_3, }; -static const struct qcom_pcie_cfg ipq4019_cfg = { +static const struct qcom_pcie_cfg cfg_2_4_0 = { .ops = &ops_2_4_0, }; -static const struct qcom_pcie_cfg sa8540p_cfg = { - .ops = &ops_1_9_0, -}; - -static const struct qcom_pcie_cfg sc8280xp_cfg = { - .ops = &ops_1_9_0, -}; - -static const struct qcom_pcie_cfg sdm845_cfg = { +static const struct qcom_pcie_cfg cfg_2_7_0 = { .ops = &ops_2_7_0, }; -static const struct qcom_pcie_cfg sm8150_cfg = { - /* sm8150 has qcom IP rev 1.5.0. However 1.5.0 ops are same as - * 1.9.0, so reuse the same. - */ - .ops = &ops_1_9_0, -}; - -static const struct qcom_pcie_cfg sm8250_cfg = { - .ops = &ops_1_9_0, -}; - -static const struct qcom_pcie_cfg sm8450_pcie0_cfg = { - .ops = &ops_1_9_0, -}; - -static const struct qcom_pcie_cfg sm8450_pcie1_cfg = { - .ops = &ops_1_9_0, -}; - -static const struct qcom_pcie_cfg sc7280_cfg = { - .ops = &ops_1_9_0, -}; - -static const struct qcom_pcie_cfg sc8180x_cfg = { - .ops = &ops_1_9_0, -}; - -static const struct qcom_pcie_cfg ipq6018_cfg = { +static const struct qcom_pcie_cfg cfg_2_9_0 = { .ops = &ops_2_9_0, }; @@ -1763,24 +1732,24 @@ err_pm_runtime_put: } static const struct of_device_id qcom_pcie_match[] = { - { .compatible = "qcom,pcie-apq8084", .data = &apq8084_cfg }, - { .compatible = "qcom,pcie-ipq8064", .data = &ipq8064_cfg }, - { .compatible = "qcom,pcie-ipq8064-v2", .data = &ipq8064_cfg }, - { .compatible = "qcom,pcie-apq8064", .data = &ipq8064_cfg }, - { .compatible = "qcom,pcie-msm8996", .data = &msm8996_cfg }, - { .compatible = "qcom,pcie-ipq8074", .data = &ipq8074_cfg }, - { .compatible = "qcom,pcie-ipq4019", .data = &ipq4019_cfg }, - { .compatible = "qcom,pcie-qcs404", .data = &ipq4019_cfg }, - { .compatible = "qcom,pcie-sa8540p", .data = &sa8540p_cfg }, - { .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg }, - { .compatible = "qcom,pcie-sm8150", .data = &sm8150_cfg }, - { .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg }, - { .compatible = "qcom,pcie-sc8180x", .data = &sc8180x_cfg }, - { .compatible = "qcom,pcie-sc8280xp", .data = &sc8280xp_cfg }, - { .compatible = "qcom,pcie-sm8450-pcie0", .data = &sm8450_pcie0_cfg }, - { .compatible = "qcom,pcie-sm8450-pcie1", .data = &sm8450_pcie1_cfg }, - { .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg }, - { .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg }, + { .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 }, + { .compatible = "qcom,pcie-ipq8064", .data = &cfg_2_1_0 }, + { .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 }, + { .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 }, + { .compatible = "qcom,pcie-msm8996", .data = &cfg_2_3_2 }, + { .compatible = "qcom,pcie-ipq8074", .data = &cfg_2_3_3 }, + { .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 }, + { .compatible = "qcom,pcie-qcs404", .data = &cfg_2_4_0 }, + { .compatible = "qcom,pcie-sa8540p", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sdm845", .data = &cfg_2_7_0 }, + { .compatible = "qcom,pcie-sm8150", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sm8250", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sc8180x", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sc8280xp", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sc7280", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 }, { } }; From d6cbfcd24443e51fb596fdbf25679d61052a3f84 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 Jul 2022 09:13:48 +0200 Subject: [PATCH 043/401] PCI: qcom: Sort device-id table Sort the device-id table entries alphabetically by compatible string to make it easier to find entries and add new ones. Link: https://lore.kernel.org/r/20220714071348.6792-9-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi Reviewed-by: Brian Masney Acked-by: Stanimir Varbanov --- drivers/pci/controller/dwc/pcie-qcom.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index ade3704ba6ea..39ca06ffe614 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1732,24 +1732,24 @@ err_pm_runtime_put: } static const struct of_device_id qcom_pcie_match[] = { + { .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 }, { .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 }, + { .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 }, + { .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 }, { .compatible = "qcom,pcie-ipq8064", .data = &cfg_2_1_0 }, { .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 }, - { .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 }, - { .compatible = "qcom,pcie-msm8996", .data = &cfg_2_3_2 }, { .compatible = "qcom,pcie-ipq8074", .data = &cfg_2_3_3 }, - { .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 }, + { .compatible = "qcom,pcie-msm8996", .data = &cfg_2_3_2 }, { .compatible = "qcom,pcie-qcs404", .data = &cfg_2_4_0 }, { .compatible = "qcom,pcie-sa8540p", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sc7280", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sc8180x", .data = &cfg_1_9_0 }, + { .compatible = "qcom,pcie-sc8280xp", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sdm845", .data = &cfg_2_7_0 }, { .compatible = "qcom,pcie-sm8150", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sm8250", .data = &cfg_1_9_0 }, - { .compatible = "qcom,pcie-sc8180x", .data = &cfg_1_9_0 }, - { .compatible = "qcom,pcie-sc8280xp", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 }, - { .compatible = "qcom,pcie-sc7280", .data = &cfg_1_9_0 }, - { .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 }, { } }; From 2e379ac66d4b734ba0e6dbdbc20f774d91be090b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 12 Aug 2022 16:11:15 +0200 Subject: [PATCH 044/401] PCI: mvebu: Fix endianness when accessing PCI emul bridge members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PCI emul bridge members iolimitupper, iobaseupper, memlimit and membase are of type __le16, so correctly access these members using le16_to_cpu() macros. Link: https://lore.kernel.org/r/20220812141115.24082-1-pali@kernel.org Fixes: e7a01876729c ("PCI: mvebu: Propagate errors when updating PCI_IO_BASE and PCI_MEM_BASE registers") Reported-by: kernel test robot Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/pci-mvebu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index af915c951f06..3639327c7cd1 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c @@ -523,7 +523,7 @@ static int mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) /* Are the new iobase/iolimit values invalid? */ if (conf->iolimit < conf->iobase || - conf->iolimitupper < conf->iobaseupper) + le16_to_cpu(conf->iolimitupper) < le16_to_cpu(conf->iobaseupper)) return mvebu_pcie_set_window(port, port->io_target, port->io_attr, &desired, &port->iowin); @@ -535,10 +535,10 @@ static int mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) * is the CPU address. */ desired.remap = ((conf->iobase & 0xF0) << 8) | - (conf->iobaseupper << 16); + (le16_to_cpu(conf->iobaseupper) << 16); desired.base = port->pcie->io.start + desired.remap; desired.size = ((0xFFF | ((conf->iolimit & 0xF0) << 8) | - (conf->iolimitupper << 16)) - + (le16_to_cpu(conf->iolimitupper) << 16)) - desired.remap) + 1; @@ -552,7 +552,7 @@ static int mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) struct pci_bridge_emul_conf *conf = &port->bridge.conf; /* Are the new membase/memlimit values invalid? */ - if (conf->memlimit < conf->membase) + if (le16_to_cpu(conf->memlimit) < le16_to_cpu(conf->membase)) return mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired, &port->memwin); @@ -562,8 +562,8 @@ static int mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) * window to setup, according to the PCI-to-PCI bridge * specifications. */ - desired.base = ((conf->membase & 0xFFF0) << 16); - desired.size = (((conf->memlimit & 0xFFF0) << 16) | 0xFFFFF) - + desired.base = ((le16_to_cpu(conf->membase) & 0xFFF0) << 16); + desired.size = (((le16_to_cpu(conf->memlimit) & 0xFFF0) << 16) | 0xFFFFF) - desired.base + 1; return mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired, From 034fdac01fe5184e63d8af901ddb9c9a329f6902 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 5 May 2022 10:39:07 +0200 Subject: [PATCH 045/401] PCI: mediatek-gen3: Change driver name to mtk-pcie-gen3 driver_register() will refuse to register another driver with the same name. This change allows pcie-mediatek-gen3 to coexist with pcie-mediatek built into the kernel. Link: https://lore.kernel.org/r/20220505083907.86598-1-nbd@nbd.name Fixes: d3bf75b579b9 ("PCI: mediatek-gen3: Add MediaTek Gen3 driver for MT8192") Signed-off-by: Felix Fietkau Signed-off-by: Lorenzo Pieralisi Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Jianjun Wang --- drivers/pci/controller/pcie-mediatek-gen3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 11cdb9b6f109..b8612ce5f4d0 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -1071,7 +1071,7 @@ static struct platform_driver mtk_pcie_driver = { .probe = mtk_pcie_probe, .remove = mtk_pcie_remove, .driver = { - .name = "mtk-pcie", + .name = "mtk-pcie-gen3", .of_match_table = mtk_pcie_of_match, .pm = &mtk_pcie_pm_ops, }, From 7f08e806a03e0453a0de27137b668d4de52fcd49 Mon Sep 17 00:00:00 2001 From: Jianjun Wang Date: Tue, 2 Aug 2022 20:06:24 +0800 Subject: [PATCH 046/401] dt-bindings: PCI: mediatek-gen3: Add support for MT8188 and MT8195 MT8188 and MT8195 are ARM platform SoCs with the same PCIe IP as MT8192. Also add new clock name "peri_mem" since the MT8188 and MT8195 use clock "peri_mem" instead of "top_133m". Link: https://lore.kernel.org/r/20220802120624.19258-1-jianjun.wang@mediatek.com Signed-off-by: Jianjun Wang Signed-off-by: Lorenzo Pieralisi Reviewed-by: Krzysztof Kozlowski --- .../devicetree/bindings/pci/mediatek-pcie-gen3.yaml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml index 0499b94627ae..c00be39af64e 100644 --- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml @@ -48,7 +48,13 @@ allOf: properties: compatible: - const: mediatek,mt8192-pcie + oneOf: + - items: + - enum: + - mediatek,mt8188-pcie + - mediatek,mt8195-pcie + - const: mediatek,mt8192-pcie + - const: mediatek,mt8192-pcie reg: maxItems: 1 @@ -84,7 +90,9 @@ properties: - const: tl_96m - const: tl_32k - const: peri_26m - - const: top_133m + - enum: + - top_133m # for MT8192 + - peri_mem # for MT8188/MT8195 assigned-clocks: maxItems: 1 @@ -126,6 +134,7 @@ required: - interrupts - ranges - clocks + - clock-names - '#interrupt-cells' - interrupt-controller From b408fad61d34c765c3e01895286332af2d50402a Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Sat, 20 Aug 2022 00:14:10 +0100 Subject: [PATCH 047/401] dt-bindings: PCI: fu740-pci: fix missing clock-names The commit b92225b034c0 ("dt-bindings: PCI: designware: Fix 'unevaluatedProperties' warnings") removed the clock-names property as a requirement and from the example as it triggered unevaluatedProperty warnings. dtbs_check was not able to pick up on this at the time, but now can: arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dtb: pcie@e00000000: Unevaluated properties are not allowed ('clock-names' was unexpected) From schema: linux/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml The property was already in use by the FU740 DTS and the clock must be enabled. The Linux and FreeBSD drivers require the property to enable the clocks correctly Re-add the property and its "clocks" dependency, while making it required. Link: https://lore.kernel.org/r/20220819231415.3860210-2-mail@conchuod.ie Fixes: b92225b034c0 ("dt-bindings: PCI: designware: Fix 'unevaluatedProperties' warnings") Fixes: 43cea116be0b ("dt-bindings: PCI: Add SiFive FU740 PCIe host controller") Signed-off-by: Conor Dooley Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring --- .../devicetree/bindings/pci/sifive,fu740-pcie.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml index 195e6afeb169..844fc7142302 100644 --- a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml @@ -51,6 +51,12 @@ properties: description: A phandle to the PCIe power up reset line. maxItems: 1 + clocks: + maxItems: 1 + + clock-names: + const: pcie_aux + pwren-gpios: description: Should specify the GPIO for controlling the PCI bus device power on. maxItems: 1 @@ -66,6 +72,7 @@ required: - interrupt-map-mask - interrupt-map - clocks + - clock-names - resets - pwren-gpios - reset-gpios @@ -104,6 +111,7 @@ examples: <0x0 0x0 0x0 0x2 &plic0 58>, <0x0 0x0 0x0 0x3 &plic0 59>, <0x0 0x0 0x0 0x4 &plic0 60>; + clock-names = "pcie_aux"; clocks = <&prci FU740_PRCI_CLK_PCIE_AUX>; resets = <&prci 4>; pwren-gpios = <&gpio 5 0>; From 05a5741019a524ab9e1d355528c8ebcbd6debfe7 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Sat, 20 Aug 2022 00:14:11 +0100 Subject: [PATCH 048/401] dt-bindings: PCI: microchip,pcie-host: fix missing clocks properties Recent versions of dt-schema warn about unevaluatedProperties: arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dtb: pcie@2000000000: Unevaluated properties are not allowed ('clock-names', 'clocks', 'legacy-interrupt-controller', 'microchip,axi-m-atr0' were unexpected) From schema: Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml The clocks are required to enable interfaces between the FPGA fabric and the core complex, so add them to the binding. Link: https://lore.kernel.org/r/20220819231415.3860210-3-mail@conchuod.ie Fixes: 6ee6c89aac35 ("dt-bindings: PCI: microchip: Add Microchip PolarFire host binding") Signed-off-by: Conor Dooley Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring --- .../bindings/pci/microchip,pcie-host.yaml | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml index edb4f81253c8..6fbe62f4da93 100644 --- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml +++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml @@ -25,6 +25,33 @@ properties: - const: cfg - const: apb + clocks: + description: + Fabric Interface Controllers, FICs, are the interface between the FPGA + fabric and the core complex on PolarFire SoC. The FICs require two clocks, + one from each side of the interface. The "FIC clocks" described by this + property are on the core complex side & communication through a FIC is not + possible unless it's corresponding clock is enabled. A clock must be + enabled for each of the interfaces the root port is connected through. + This could in theory be all 4 interfaces, one interface or any combination + in between. + minItems: 1 + items: + - description: FIC0's clock + - description: FIC1's clock + - description: FIC2's clock + - description: FIC3's clock + + clock-names: + description: + As any FIC connection combination is possible, the names should match the + order in the clocks property and take the form "ficN" where N is a number + 0-3 + minItems: 1 + maxItems: 4 + items: + pattern: '^fic[0-3]$' + interrupts: minItems: 1 items: From 1a7966b33b5bbefd950cffef1ea8ee3f5f1bf076 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Sat, 20 Aug 2022 00:14:12 +0100 Subject: [PATCH 049/401] dt-bindings: PCI: microchip,pcie-host: fix missing dma-ranges The dma-ranges property was missed when adding the binding initially. The root port can use up to 6 address translation tables, depending on configuration. Link: https://www.microsemi.com/document-portal/doc_download/1245812-polarfire-fpga-and-polarfire-soc-fpga-pci-express-user-guide # Section 1.3.3 Link: https://lore.kernel.org/r/20220819231415.3860210-4-mail@conchuod.ie Fixes: 6ee6c89aac35 ("dt-bindings: PCI: microchip: Add Microchip PolarFire host binding") Signed-off-by: Conor Dooley Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring --- .../devicetree/bindings/pci/microchip,pcie-host.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml index 6fbe62f4da93..23d95c65acff 100644 --- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml +++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml @@ -67,6 +67,10 @@ properties: ranges: maxItems: 1 + dma-ranges: + minItems: 1 + maxItems: 6 + msi-controller: description: Identifies the node as an MSI controller. From 28a71499744133614da6ca1f9adc4d4044d6f417 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 19 Aug 2022 07:38:17 +0530 Subject: [PATCH 050/401] MAINTAINERS: Add Manivannan Sadhasivam as PCI Endpoint reviewer I've been reviewing the patches related to PCI Endpoint Subsystem for some time. So I'd like to add myself as the reviewer to get immediate attention to the patches. Link: https://lore.kernel.org/r/20220819020817.197844-1-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Acked-by: Kishon Vijay Abraham I --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8a5012ba6ff9..f60dfac7661c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15682,6 +15682,7 @@ PCI ENDPOINT SUBSYSTEM M: Kishon Vijay Abraham I M: Lorenzo Pieralisi R: Krzysztof Wilczyński +R: Manivannan Sadhasivam L: linux-pci@vger.kernel.org S: Supported Q: https://patchwork.kernel.org/project/linux-pci/list/ From 8d39e55e52c10f78967d6d029631601fcc8a0121 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 16 Aug 2022 07:49:14 +0200 Subject: [PATCH 051/401] dt-binding: pinctrl: Add cypress,cy8c95x0 Added device tree binding documentation for Cypress CY8C95x0 I2C pin-controller. Signed-off-by: Patrick Rudolph Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220816054917.7893-2-patrick.rudolph@9elements.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/cypress,cy8c95x0.yaml | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/cypress,cy8c95x0.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/cypress,cy8c95x0.yaml b/Documentation/devicetree/bindings/pinctrl/cypress,cy8c95x0.yaml new file mode 100644 index 000000000000..915cbbcc3555 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/cypress,cy8c95x0.yaml @@ -0,0 +1,134 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/cypress,cy8c95x0.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cypress CY8C95X0 I2C GPIO expander + +maintainers: + - Patrick Rudolph + +description: | + This supports the 20/40/60 pin Cypress CYC95x0 GPIO I2C expanders. + Pin function configuration is performed on a per-pin basis. + +properties: + compatible: + enum: + - cypress,cy8c9520 + - cypress,cy8c9540 + - cypress,cy8c9560 + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + description: + The first cell is the GPIO number and the second cell specifies GPIO + flags, as defined in . + const: 2 + + interrupts: + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + + gpio-line-names: true + + gpio-ranges: + maxItems: 1 + + gpio-reserved-ranges: + maxItems: 1 + + vdd-supply: + description: + Optional power supply. + +patternProperties: + '-pins$': + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: pincfg-node.yaml# + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + pattern: '^gp([0-7][0-7])$' + minItems: 1 + maxItems: 60 + + function: + description: + Specify the alternative function to be configured for the specified + pins. + enum: [ gpio, pwm ] + + bias-pull-down: true + + bias-pull-up: true + + bias-disable: true + + output-high: true + + output-low: true + + drive-push-pull: true + + drive-open-drain: true + + drive-open-source: true + + required: + - pins + - function + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - '#interrupt-cells' + - gpio-controller + - '#gpio-cells' + +additionalProperties: false + +allOf: + - $ref: "pinctrl.yaml#" + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pinctrl@20 { + compatible = "cypress,cy8c9520"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupts = ; + interrupt-controller; + vdd-supply = <&p3v3>; + gpio-reserved-ranges = <5 1>; + }; + }; From e6cbbe42944de93ba4e0785b4f90d284b1d7cdf6 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 16 Aug 2022 07:49:15 +0200 Subject: [PATCH 052/401] pinctrl: Add Cypress cy8c95x0 support Add support for cypress I2C GPIO expanders cy8c9520, cy8c9540 and cy8c9560. The GPIO expanders feature a PWM mode, thus add it as pinctrl driver. The chip features multiple drive modes for each pin when configured as output and multiple bias settings when configured as input. Tested all three components and verified that all functionality is fully working. Datasheet: https://www.cypress.com/file/37971/download Signed-off-by: Patrick Rudolph Signed-off-by: Naresh Solanki Link: https://lore.kernel.org/r/20220816054917.7893-3-patrick.rudolph@9elements.com Signed-off-by: Linus Walleij --- MAINTAINERS | 6 + drivers/pinctrl/Kconfig | 14 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-cy8c95x0.c | 1381 ++++++++++++++++++++++++++++ 4 files changed, 1402 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-cy8c95x0.c diff --git a/MAINTAINERS b/MAINTAINERS index 8a5012ba6ff9..131299c18f02 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5629,6 +5629,12 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ T: git git://linuxtv.org/anttip/media_tree.git F: drivers/media/common/cypress_firmware* +CYPRESS CY8C95X0 PINCTRL DRIVER +M: Patrick Rudolph +L: linux-gpio@vger.kernel.org +S: Maintained +F: drivers/pinctrl/pinctrl-cy8c95x0.c + CYPRESS CY8CTMA140 TOUCHSCREEN DRIVER M: Linus Walleij L: linux-input@vger.kernel.org diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 1cf74b0c42e5..fc0e529e633f 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -135,6 +135,20 @@ config PINCTRL_BM1880 help Pinctrl driver for Bitmain BM1880 SoC. +config PINCTRL_CY8C95X0 + tristate "Cypress CY8C95X0 I2C pinctrl and GPIO driver" + depends on I2C && OF + select GPIOLIB + select GPIOLIB_IRQCHIP + select PINMUX + select PINCONF + select GENERIC_PINCONF + select REGMAP_I2C + help + Support for 20/40/60 pin Cypress Cy8C95x0 pinctrl/gpio I2C expander. + This driver can also be built as a module. If so, the module will be + called pinctrl-cy8c95x0. + config PINCTRL_DA850_PUPD tristate "TI DA850/OMAP-L138/AM18XX pull-up and pull-down groups" depends on OF && (ARCH_DAVINCI_DA850 || COMPILE_TEST) diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index e76f5cdc64b0..7188dab7eec8 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o +obj-$(CONFIG_PINCTRL_CY8C95X0) += pinctrl-cy8c95x0.o obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o obj-$(CONFIG_PINCTRL_DA9062) += pinctrl-da9062.o obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c new file mode 100644 index 000000000000..a29df0920f4f --- /dev/null +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -0,0 +1,1381 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * CY8C95X0 20/40/60 pin I2C GPIO port expander with interrupt support + * + * Copyright (C) 2022 9elements GmbH + * Author: Patrick Rudolph + * Author: Naresh Solanki + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Fast access registers */ +#define CY8C95X0_INPUT 0x00 +#define CY8C95X0_OUTPUT 0x08 +#define CY8C95X0_INTSTATUS 0x10 + +#define CY8C95X0_INPUT_(x) (CY8C95X0_INPUT + (x)) +#define CY8C95X0_OUTPUT_(x) (CY8C95X0_OUTPUT + (x)) +#define CY8C95X0_INTSTATUS_(x) (CY8C95X0_INTSTATUS + (x)) + +/* Port Select configures the port */ +#define CY8C95X0_PORTSEL 0x18 +/* port settings, write PORTSEL first */ +#define CY8C95X0_INTMASK 0x19 +#define CY8C95X0_PWMSEL 0x1A +#define CY8C95X0_INVERT 0x1B +#define CY8C95X0_DIRECTION 0x1C +/* Drive mode register change state on writing '1' */ +#define CY8C95X0_DRV_PU 0x1D +#define CY8C95X0_DRV_PD 0x1E +#define CY8C95X0_DRV_ODH 0x1F +#define CY8C95X0_DRV_ODL 0x20 +#define CY8C95X0_DRV_PP_FAST 0x21 +#define CY8C95X0_DRV_PP_SLOW 0x22 +#define CY8C95X0_DRV_HIZ 0x23 +#define CY8C95X0_DEVID 0x2E +#define CY8C95X0_WATCHDOG 0x2F +#define CY8C95X0_COMMAND 0x30 + +#define CY8C95X0_PIN_TO_OFFSET(x) (((x) >= 20) ? ((x) + 4) : (x)) + +static const struct i2c_device_id cy8c95x0_id[] = { + { "cy8c9520", 20, }, + { "cy8c9540", 40, }, + { "cy8c9560", 60, }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cy8c95x0_id); + +#define OF_CY8C95X(__nrgpio) ((void *)(__nrgpio)) + +static const struct of_device_id cy8c95x0_dt_ids[] = { + { .compatible = "cypress,cy8c9520", .data = OF_CY8C95X(20), }, + { .compatible = "cypress,cy8c9540", .data = OF_CY8C95X(40), }, + { .compatible = "cypress,cy8c9560", .data = OF_CY8C95X(60), }, + { } +}; + +MODULE_DEVICE_TABLE(of, cy8c95x0_dt_ids); + +#define MAX_BANK 8 +#define BANK_SZ 8 +#define MAX_LINE (MAX_BANK * BANK_SZ) + +#define CY8C95X0_GPIO_MASK GENMASK(7, 0) + +/** + * struct cy8c95x0_pinctrl - driver data + * @regmap: Device's regmap + * @irq_lock: IRQ bus lock + * @i2c_lock: Mutex for the device internal mux register + * @irq_mask: I/O bits affected by interrupts + * @irq_trig_raise: I/O bits affected by raising voltage level + * @irq_trig_fall: I/O bits affected by falling voltage level + * @irq_trig_low: I/O bits affected by a low voltage level + * @irq_trig_high: I/O bits affected by a high voltage level + * @push_pull: I/O bits configured as push pull driver + * @shiftmask: Mask used to compensate for Gport2 width + * @irq_chip: IRQ chip configuration + * @nport: Number of Gports in this chip + * @gpio_chip: gpiolib chip + * @driver_data: private driver data + * @regulator: Pointer to the regulator for the IC + * @dev: struct device + * @pctldev: pin controller device + * @pinctrl_desc: pin controller description + * @name: Chip controller name + * @tpin: Total number of pins + */ +struct cy8c95x0_pinctrl { + struct regmap *regmap; + struct mutex irq_lock; + struct mutex i2c_lock; + DECLARE_BITMAP(irq_mask, MAX_LINE); + DECLARE_BITMAP(irq_trig_raise, MAX_LINE); + DECLARE_BITMAP(irq_trig_fall, MAX_LINE); + DECLARE_BITMAP(irq_trig_low, MAX_LINE); + DECLARE_BITMAP(irq_trig_high, MAX_LINE); + DECLARE_BITMAP(push_pull, MAX_LINE); + DECLARE_BITMAP(shiftmask, MAX_LINE); + struct irq_chip irq_chip; + int nport; + struct gpio_chip gpio_chip; + unsigned long driver_data; + struct regulator *regulator; + struct device *dev; + struct pinctrl_dev *pctldev; + struct pinctrl_desc pinctrl_desc; + char name[32]; + unsigned int tpin; +}; + +static const struct pinctrl_pin_desc cy8c9560_pins[] = { + PINCTRL_PIN(0, "gp00"), + PINCTRL_PIN(1, "gp01"), + PINCTRL_PIN(2, "gp02"), + PINCTRL_PIN(3, "gp03"), + PINCTRL_PIN(4, "gp04"), + PINCTRL_PIN(5, "gp05"), + PINCTRL_PIN(6, "gp06"), + PINCTRL_PIN(7, "gp07"), + + PINCTRL_PIN(8, "gp10"), + PINCTRL_PIN(9, "gp11"), + PINCTRL_PIN(10, "gp12"), + PINCTRL_PIN(11, "gp13"), + PINCTRL_PIN(12, "gp14"), + PINCTRL_PIN(13, "gp15"), + PINCTRL_PIN(14, "gp16"), + PINCTRL_PIN(15, "gp17"), + + PINCTRL_PIN(16, "gp20"), + PINCTRL_PIN(17, "gp21"), + PINCTRL_PIN(18, "gp22"), + PINCTRL_PIN(19, "gp23"), + + PINCTRL_PIN(20, "gp30"), + PINCTRL_PIN(21, "gp31"), + PINCTRL_PIN(22, "gp32"), + PINCTRL_PIN(23, "gp33"), + PINCTRL_PIN(24, "gp34"), + PINCTRL_PIN(25, "gp35"), + PINCTRL_PIN(26, "gp36"), + PINCTRL_PIN(27, "gp37"), + + PINCTRL_PIN(28, "gp40"), + PINCTRL_PIN(29, "gp41"), + PINCTRL_PIN(30, "gp42"), + PINCTRL_PIN(31, "gp43"), + PINCTRL_PIN(32, "gp44"), + PINCTRL_PIN(33, "gp45"), + PINCTRL_PIN(34, "gp46"), + PINCTRL_PIN(35, "gp47"), + + PINCTRL_PIN(36, "gp50"), + PINCTRL_PIN(37, "gp51"), + PINCTRL_PIN(38, "gp52"), + PINCTRL_PIN(39, "gp53"), + PINCTRL_PIN(40, "gp54"), + PINCTRL_PIN(41, "gp55"), + PINCTRL_PIN(42, "gp56"), + PINCTRL_PIN(43, "gp57"), + + PINCTRL_PIN(44, "gp60"), + PINCTRL_PIN(45, "gp61"), + PINCTRL_PIN(46, "gp62"), + PINCTRL_PIN(47, "gp63"), + PINCTRL_PIN(48, "gp64"), + PINCTRL_PIN(49, "gp65"), + PINCTRL_PIN(50, "gp66"), + PINCTRL_PIN(51, "gp67"), + + PINCTRL_PIN(52, "gp70"), + PINCTRL_PIN(53, "gp71"), + PINCTRL_PIN(54, "gp72"), + PINCTRL_PIN(55, "gp73"), + PINCTRL_PIN(56, "gp74"), + PINCTRL_PIN(57, "gp75"), + PINCTRL_PIN(58, "gp76"), + PINCTRL_PIN(59, "gp77"), +}; + +static const char * const cy8c95x0_groups[] = { + "gp00", + "gp01", + "gp02", + "gp03", + "gp04", + "gp05", + "gp06", + "gp07", + + "gp10", + "gp11", + "gp12", + "gp13", + "gp14", + "gp15", + "gp16", + "gp17", + + "gp20", + "gp21", + "gp22", + "gp23", + + "gp30", + "gp31", + "gp32", + "gp33", + "gp34", + "gp35", + "gp36", + "gp37", + + "gp40", + "gp41", + "gp42", + "gp43", + "gp44", + "gp45", + "gp46", + "gp47", + + "gp50", + "gp51", + "gp52", + "gp53", + "gp54", + "gp55", + "gp56", + "gp57", + + "gp60", + "gp61", + "gp62", + "gp63", + "gp64", + "gp65", + "gp66", + "gp67", + + "gp70", + "gp71", + "gp72", + "gp73", + "gp74", + "gp75", + "gp76", + "gp77", +}; + +static inline u8 cypress_get_port(struct cy8c95x0_pinctrl *chip, unsigned int pin) +{ + /* Account for GPORT2 which only has 4 bits */ + return CY8C95X0_PIN_TO_OFFSET(pin) / BANK_SZ; +} + +static int cypress_get_pin_mask(struct cy8c95x0_pinctrl *chip, unsigned int pin) +{ + /* Account for GPORT2 which only has 4 bits */ + return BIT(CY8C95X0_PIN_TO_OFFSET(pin) % BANK_SZ); +} + +static bool cy8c95x0_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0x24 ... 0x27: + return false; + } + + return true; +} + +static bool cy8c95x0_writeable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CY8C95X0_INPUT_(0) ... CY8C95X0_INPUT_(7): + return false; + case CY8C95X0_DEVID: + return false; + case 0x24 ... 0x27: + return false; + } + + return true; +} + +static bool cy8c95x0_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CY8C95X0_INPUT_(0) ... CY8C95X0_INPUT_(7): + case CY8C95X0_INTSTATUS_(0) ... CY8C95X0_INTSTATUS_(7): + case CY8C95X0_INTMASK: + case CY8C95X0_INVERT: + case CY8C95X0_PWMSEL: + case CY8C95X0_DIRECTION: + case CY8C95X0_DRV_PU: + case CY8C95X0_DRV_PD: + case CY8C95X0_DRV_ODH: + case CY8C95X0_DRV_ODL: + case CY8C95X0_DRV_PP_FAST: + case CY8C95X0_DRV_PP_SLOW: + case CY8C95X0_DRV_HIZ: + return true; + } + + return false; +} + +static bool cy8c95x0_precious_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CY8C95X0_INTSTATUS_(0) ... CY8C95X0_INTSTATUS_(7): + return true; + } + + return false; +} + +static const struct reg_default cy8c95x0_reg_defaults[] = { + { CY8C95X0_OUTPUT_(0), 0xff }, + { CY8C95X0_OUTPUT_(1), 0xff }, + { CY8C95X0_OUTPUT_(2), 0xff }, + { CY8C95X0_OUTPUT_(3), 0xff }, + { CY8C95X0_OUTPUT_(4), 0xff }, + { CY8C95X0_OUTPUT_(5), 0xff }, + { CY8C95X0_OUTPUT_(6), 0xff }, + { CY8C95X0_OUTPUT_(7), 0xff }, + { CY8C95X0_PORTSEL, 0 }, + { CY8C95X0_PWMSEL, 0 }, +}; + +static const struct regmap_config cy8c95x0_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .reg_defaults = cy8c95x0_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(cy8c95x0_reg_defaults), + + .readable_reg = cy8c95x0_readable_register, + .writeable_reg = cy8c95x0_writeable_register, + .volatile_reg = cy8c95x0_volatile_register, + .precious_reg = cy8c95x0_precious_register, + + .cache_type = REGCACHE_FLAT, + .max_register = CY8C95X0_COMMAND, +}; + +static int cy8c95x0_write_regs_mask(struct cy8c95x0_pinctrl *chip, int reg, + unsigned long *val, unsigned long *mask) +{ + DECLARE_BITMAP(tmask, MAX_LINE); + DECLARE_BITMAP(tval, MAX_LINE); + int write_val; + int ret = 0; + int i, off = 0; + u8 bits; + + /* Add the 4 bit gap of Gport2 */ + bitmap_andnot(tmask, mask, chip->shiftmask, MAX_LINE); + bitmap_shift_left(tmask, tmask, 4, MAX_LINE); + bitmap_replace(tmask, tmask, mask, chip->shiftmask, BANK_SZ * 3); + + bitmap_andnot(tval, val, chip->shiftmask, MAX_LINE); + bitmap_shift_left(tval, tval, 4, MAX_LINE); + bitmap_replace(tval, tval, val, chip->shiftmask, BANK_SZ * 3); + + mutex_lock(&chip->i2c_lock); + for (i = 0; i < chip->nport; i++) { + /* Skip over unused banks */ + bits = bitmap_get_value8(tmask, i * BANK_SZ); + if (!bits) + continue; + + switch (reg) { + /* muxed registers */ + case CY8C95X0_INTMASK: + case CY8C95X0_PWMSEL: + case CY8C95X0_INVERT: + case CY8C95X0_DIRECTION: + case CY8C95X0_DRV_PU: + case CY8C95X0_DRV_PD: + case CY8C95X0_DRV_ODH: + case CY8C95X0_DRV_ODL: + case CY8C95X0_DRV_PP_FAST: + case CY8C95X0_DRV_PP_SLOW: + case CY8C95X0_DRV_HIZ: + ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, i); + if (ret < 0) + goto out; + off = reg; + break; + /* direct access registers */ + case CY8C95X0_INPUT: + case CY8C95X0_OUTPUT: + case CY8C95X0_INTSTATUS: + off = reg + i; + break; + default: + ret = -EINVAL; + goto out; + } + + write_val = bitmap_get_value8(tval, i * BANK_SZ); + + ret = regmap_update_bits(chip->regmap, off, bits, write_val); + if (ret < 0) + goto out; + } +out: + mutex_unlock(&chip->i2c_lock); + + if (ret < 0) + dev_err(chip->dev, "failed writing register %d: err %d\n", off, ret); + + return ret; +} + +static int cy8c95x0_read_regs_mask(struct cy8c95x0_pinctrl *chip, int reg, + unsigned long *val, unsigned long *mask) +{ + DECLARE_BITMAP(tmask, MAX_LINE); + DECLARE_BITMAP(tval, MAX_LINE); + DECLARE_BITMAP(tmp, MAX_LINE); + int read_val; + int ret = 0; + int i, off = 0; + u8 bits; + + /* Add the 4 bit gap of Gport2 */ + bitmap_andnot(tmask, mask, chip->shiftmask, MAX_LINE); + bitmap_shift_left(tmask, tmask, 4, MAX_LINE); + bitmap_replace(tmask, tmask, mask, chip->shiftmask, BANK_SZ * 3); + + bitmap_andnot(tval, val, chip->shiftmask, MAX_LINE); + bitmap_shift_left(tval, tval, 4, MAX_LINE); + bitmap_replace(tval, tval, val, chip->shiftmask, BANK_SZ * 3); + + mutex_lock(&chip->i2c_lock); + for (i = 0; i < chip->nport; i++) { + /* Skip over unused banks */ + bits = bitmap_get_value8(tmask, i * BANK_SZ); + if (!bits) + continue; + + switch (reg) { + /* muxed registers */ + case CY8C95X0_INTMASK: + case CY8C95X0_PWMSEL: + case CY8C95X0_INVERT: + case CY8C95X0_DIRECTION: + case CY8C95X0_DRV_PU: + case CY8C95X0_DRV_PD: + case CY8C95X0_DRV_ODH: + case CY8C95X0_DRV_ODL: + case CY8C95X0_DRV_PP_FAST: + case CY8C95X0_DRV_PP_SLOW: + case CY8C95X0_DRV_HIZ: + ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, i); + if (ret < 0) + goto out; + off = reg; + break; + /* direct access registers */ + case CY8C95X0_INPUT: + case CY8C95X0_OUTPUT: + case CY8C95X0_INTSTATUS: + off = reg + i; + break; + default: + ret = -EINVAL; + goto out; + } + + ret = regmap_read(chip->regmap, off, &read_val); + if (ret < 0) + goto out; + + read_val &= bits; + read_val |= bitmap_get_value8(tval, i * BANK_SZ) & ~bits; + bitmap_set_value8(tval, read_val, i * BANK_SZ); + } + + /* Fill the 4 bit gap of Gport2 */ + bitmap_shift_right(tmp, tval, 4, MAX_LINE); + bitmap_replace(val, tmp, tval, chip->shiftmask, MAX_LINE); + +out: + mutex_unlock(&chip->i2c_lock); + + if (ret < 0) + dev_err(chip->dev, "failed reading register %d: err %d\n", off, ret); + + return ret; +} + +static int cy8c95x0_gpio_direction_input(struct gpio_chip *gc, unsigned int off) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + u8 port = cypress_get_port(chip, off); + u8 bit = cypress_get_pin_mask(chip, off); + int ret; + + mutex_lock(&chip->i2c_lock); + ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); + if (ret) + goto out; + + ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, bit); + if (ret) + goto out; + + if (test_bit(off, chip->push_pull)) { + /* + * Disable driving the pin by forcing it to HighZ. Only setting the + * direction register isn't sufficient in Push-Pull mode. + */ + ret = regmap_write_bits(chip->regmap, CY8C95X0_DRV_HIZ, bit, bit); + if (ret) + goto out; + clear_bit(off, chip->push_pull); + } + +out: + mutex_unlock(&chip->i2c_lock); + + return ret; +} + +static int cy8c95x0_gpio_direction_output(struct gpio_chip *gc, + unsigned int off, int val) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + u8 port = cypress_get_port(chip, off); + u8 outreg = CY8C95X0_OUTPUT_(port); + u8 bit = cypress_get_pin_mask(chip, off); + int ret; + + /* set output level */ + ret = regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0); + if (ret) + return ret; + + mutex_lock(&chip->i2c_lock); + /* select port */ + ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); + if (ret) + goto out; + + /* then direction */ + ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, 0); + +out: + mutex_unlock(&chip->i2c_lock); + + return ret; +} + +static int cy8c95x0_gpio_get_value(struct gpio_chip *gc, unsigned int off) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + u8 inreg = CY8C95X0_INPUT_(cypress_get_port(chip, off)); + u8 bit = cypress_get_pin_mask(chip, off); + u32 reg_val; + int ret; + + ret = regmap_read(chip->regmap, inreg, ®_val); + if (ret < 0) { + /* + * NOTE: + * diagnostic already emitted; that's all we should + * do unless gpio_*_value_cansleep() calls become different + * from their nonsleeping siblings (and report faults). + */ + return 0; + } + + return !!(reg_val & bit); +} + +static void cy8c95x0_gpio_set_value(struct gpio_chip *gc, unsigned int off, + int val) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + u8 outreg = CY8C95X0_OUTPUT_(cypress_get_port(chip, off)); + u8 bit = cypress_get_pin_mask(chip, off); + + regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0); +} + +static int cy8c95x0_gpio_get_direction(struct gpio_chip *gc, unsigned int off) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + u8 port = cypress_get_port(chip, off); + u8 bit = cypress_get_pin_mask(chip, off); + u32 reg_val; + int ret; + + mutex_lock(&chip->i2c_lock); + + ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); + if (ret < 0) + goto out; + + ret = regmap_read(chip->regmap, CY8C95X0_DIRECTION, ®_val); + if (ret < 0) + goto out; + + mutex_unlock(&chip->i2c_lock); + + if (reg_val & bit) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; +out: + mutex_unlock(&chip->i2c_lock); + return ret; +} + +static int cy8c95x0_gpio_get_pincfg(struct cy8c95x0_pinctrl *chip, + unsigned int off, + unsigned long *config) +{ + enum pin_config_param param = pinconf_to_config_param(*config); + u8 port = cypress_get_port(chip, off); + u8 bit = cypress_get_pin_mask(chip, off); + unsigned int reg; + u32 reg_val; + u16 arg = 0; + int ret; + + mutex_lock(&chip->i2c_lock); + + /* select port */ + ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); + if (ret < 0) + goto out; + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + reg = CY8C95X0_DRV_PU; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + reg = CY8C95X0_DRV_PD; + break; + case PIN_CONFIG_BIAS_DISABLE: + reg = CY8C95X0_DRV_HIZ; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + reg = CY8C95X0_DRV_ODL; + break; + case PIN_CONFIG_DRIVE_OPEN_SOURCE: + reg = CY8C95X0_DRV_ODH; + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + reg = CY8C95X0_DRV_PP_FAST; + break; + case PIN_CONFIG_INPUT_ENABLE: + reg = CY8C95X0_DIRECTION; + break; + case PIN_CONFIG_MODE_PWM: + reg = CY8C95X0_PWMSEL; + break; + case PIN_CONFIG_OUTPUT: + reg = CY8C95X0_OUTPUT_(port); + break; + case PIN_CONFIG_OUTPUT_ENABLE: + reg = CY8C95X0_DIRECTION; + break; + + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + case PIN_CONFIG_BIAS_BUS_HOLD: + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + case PIN_CONFIG_DRIVE_STRENGTH: + case PIN_CONFIG_DRIVE_STRENGTH_UA: + case PIN_CONFIG_INPUT_DEBOUNCE: + case PIN_CONFIG_INPUT_SCHMITT: + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + case PIN_CONFIG_MODE_LOW_POWER: + case PIN_CONFIG_PERSIST_STATE: + case PIN_CONFIG_POWER_SOURCE: + case PIN_CONFIG_SKEW_DELAY: + case PIN_CONFIG_SLEEP_HARDWARE_STATE: + case PIN_CONFIG_SLEW_RATE: + default: + ret = -ENOTSUPP; + goto out; + } + /* Writing 1 to one of the drive mode registers will automatically + * clear conflicting set bits in the other drive mode registers. + */ + ret = regmap_read(chip->regmap, reg, ®_val); + if (reg_val & bit) + arg = 1; + + *config = pinconf_to_config_packed(param, (u16)arg); +out: + mutex_unlock(&chip->i2c_lock); + + return ret; +} + +static int cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl *chip, + unsigned int off, + unsigned long config) +{ + u8 port = cypress_get_port(chip, off); + u8 bit = cypress_get_pin_mask(chip, off); + unsigned long param = pinconf_to_config_param(config); + unsigned int reg; + int ret; + + mutex_lock(&chip->i2c_lock); + + /* select port */ + ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); + if (ret < 0) + goto out; + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + clear_bit(off, chip->push_pull); + reg = CY8C95X0_DRV_PU; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + clear_bit(off, chip->push_pull); + reg = CY8C95X0_DRV_PD; + break; + case PIN_CONFIG_BIAS_DISABLE: + clear_bit(off, chip->push_pull); + reg = CY8C95X0_DRV_HIZ; + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + clear_bit(off, chip->push_pull); + reg = CY8C95X0_DRV_ODL; + break; + case PIN_CONFIG_DRIVE_OPEN_SOURCE: + clear_bit(off, chip->push_pull); + reg = CY8C95X0_DRV_ODH; + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + set_bit(off, chip->push_pull); + reg = CY8C95X0_DRV_PP_FAST; + break; + case PIN_CONFIG_MODE_PWM: + reg = CY8C95X0_PWMSEL; + break; + default: + ret = -ENOTSUPP; + goto out; + } + /* Writing 1 to one of the drive mode registers will automatically + * clear conflicting set bits in the other drive mode registers. + */ + ret = regmap_write_bits(chip->regmap, reg, bit, bit); + +out: + mutex_unlock(&chip->i2c_lock); + return ret; +} + +static int cy8c95x0_gpio_set_config(struct gpio_chip *gc, unsigned int offset, + unsigned long config) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + unsigned long arg = pinconf_to_config_argument(config); + + switch (pinconf_to_config_param(config)) { + case PIN_CONFIG_INPUT_ENABLE: + return cy8c95x0_gpio_direction_input(gc, offset); + case PIN_CONFIG_OUTPUT: + return cy8c95x0_gpio_direction_output(gc, offset, arg); + case PIN_CONFIG_MODE_PWM: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + case PIN_CONFIG_DRIVE_OPEN_SOURCE: + case PIN_CONFIG_DRIVE_PUSH_PULL: + return cy8c95x0_gpio_set_pincfg(chip, offset, config); + default: + return -ENOTSUPP; + } +} + +static int cy8c95x0_gpio_get_multiple(struct gpio_chip *gc, + unsigned long *mask, unsigned long *bits) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + + return cy8c95x0_read_regs_mask(chip, CY8C95X0_INPUT, bits, mask); +} + +static void cy8c95x0_gpio_set_multiple(struct gpio_chip *gc, + unsigned long *mask, unsigned long *bits) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + + cy8c95x0_write_regs_mask(chip, CY8C95X0_OUTPUT, bits, mask); +} + +static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip, int ngpio) +{ + struct gpio_chip *gc = &chip->gpio_chip; + + gc->direction_input = cy8c95x0_gpio_direction_input; + gc->direction_output = cy8c95x0_gpio_direction_output; + gc->get = cy8c95x0_gpio_get_value; + gc->set = cy8c95x0_gpio_set_value; + gc->get_direction = cy8c95x0_gpio_get_direction; + gc->get_multiple = cy8c95x0_gpio_get_multiple; + gc->set_multiple = cy8c95x0_gpio_set_multiple; + gc->set_config = cy8c95x0_gpio_set_config; + gc->can_sleep = true; + + gc->base = -1; + gc->ngpio = ngpio; + + gc->parent = chip->dev; + gc->owner = THIS_MODULE; + gc->names = NULL; + + gc->label = dev_name(chip->dev); + + return devm_gpiochip_add_data(chip->dev, gc, chip); +} + +static void cy8c95x0_irq_mask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + + set_bit(irqd_to_hwirq(d), chip->irq_mask); +} + +static void cy8c95x0_irq_unmask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + + clear_bit(irqd_to_hwirq(d), chip->irq_mask); +} + +static void cy8c95x0_irq_bus_lock(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + + mutex_lock(&chip->irq_lock); +} + +static void cy8c95x0_irq_bus_sync_unlock(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + DECLARE_BITMAP(ones, MAX_LINE); + DECLARE_BITMAP(irq_mask, MAX_LINE); + DECLARE_BITMAP(reg_direction, MAX_LINE); + + bitmap_fill(ones, MAX_LINE); + + cy8c95x0_write_regs_mask(chip, CY8C95X0_INTMASK, chip->irq_mask, ones); + + /* Switch direction to input if needed */ + cy8c95x0_read_regs_mask(chip, CY8C95X0_DIRECTION, reg_direction, chip->irq_mask); + bitmap_or(irq_mask, chip->irq_mask, reg_direction, MAX_LINE); + bitmap_complement(irq_mask, irq_mask, MAX_LINE); + + /* Look for any newly setup interrupt */ + cy8c95x0_write_regs_mask(chip, CY8C95X0_DIRECTION, ones, irq_mask); + + mutex_unlock(&chip->irq_lock); +} + +static int cy8c95x0_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned int trig_type; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_EDGE_BOTH: + trig_type = type; + break; + case IRQ_TYPE_LEVEL_HIGH: + trig_type = IRQ_TYPE_EDGE_RISING; + break; + case IRQ_TYPE_LEVEL_LOW: + trig_type = IRQ_TYPE_EDGE_FALLING; + break; + default: + dev_err(chip->dev, "irq %d: unsupported type %d\n", d->irq, type); + return -EINVAL; + } + + assign_bit(hwirq, chip->irq_trig_fall, trig_type & IRQ_TYPE_EDGE_FALLING); + assign_bit(hwirq, chip->irq_trig_raise, trig_type & IRQ_TYPE_EDGE_RISING); + assign_bit(hwirq, chip->irq_trig_low, type == IRQ_TYPE_LEVEL_LOW); + assign_bit(hwirq, chip->irq_trig_high, type == IRQ_TYPE_LEVEL_HIGH); + + return 0; +} + +static void cy8c95x0_irq_shutdown(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + + clear_bit(hwirq, chip->irq_trig_raise); + clear_bit(hwirq, chip->irq_trig_fall); + clear_bit(hwirq, chip->irq_trig_low); + clear_bit(hwirq, chip->irq_trig_high); +} + +static bool cy8c95x0_irq_pending(struct cy8c95x0_pinctrl *chip, unsigned long *pending) +{ + DECLARE_BITMAP(ones, MAX_LINE); + DECLARE_BITMAP(cur_stat, MAX_LINE); + DECLARE_BITMAP(new_stat, MAX_LINE); + DECLARE_BITMAP(trigger, MAX_LINE); + + bitmap_fill(ones, MAX_LINE); + + /* Read the current interrupt status from the device */ + if (cy8c95x0_read_regs_mask(chip, CY8C95X0_INTSTATUS, trigger, ones)) + return false; + + /* Check latched inputs */ + if (cy8c95x0_read_regs_mask(chip, CY8C95X0_INPUT, cur_stat, trigger)) + return false; + + /* Apply filter for rising/falling edge selection */ + bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, + cur_stat, MAX_LINE); + + bitmap_and(pending, new_stat, trigger, MAX_LINE); + + return !bitmap_empty(pending, MAX_LINE); +} + +static irqreturn_t cy8c95x0_irq_handler(int irq, void *devid) +{ + struct cy8c95x0_pinctrl *chip = devid; + struct gpio_chip *gc = &chip->gpio_chip; + DECLARE_BITMAP(pending, MAX_LINE); + int nested_irq, level; + bool ret; + + ret = cy8c95x0_irq_pending(chip, pending); + if (!ret) + return IRQ_RETVAL(0); + + ret = 0; + for_each_set_bit(level, pending, MAX_LINE) { + /* Already accounted for 4bit gap in GPort2 */ + nested_irq = irq_find_mapping(gc->irq.domain, level); + + if (unlikely(nested_irq <= 0)) { + dev_warn_ratelimited(gc->parent, "unmapped interrupt %d\n", level); + continue; + } + + if (test_bit(level, chip->irq_trig_low)) + while (!cy8c95x0_gpio_get_value(gc, level)) + handle_nested_irq(nested_irq); + else if (test_bit(level, chip->irq_trig_high)) + while (cy8c95x0_gpio_get_value(gc, level)) + handle_nested_irq(nested_irq); + else + handle_nested_irq(nested_irq); + + ret = 1; + } + + return IRQ_RETVAL(ret); +} + +static int cy8c95x0_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); + + return chip->tpin; +} + +static const char *cy8c95x0_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group) +{ + return cy8c95x0_groups[group]; +} + +static int cy8c95x0_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int group, + const unsigned int **pins, + unsigned int *num_pins) +{ + struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); + + if (group >= chip->tpin) { + *pins = NULL; + *num_pins = 0; + return 0; + } + + *pins = &cy8c9560_pins[group].number; + *num_pins = 1; + return 0; +} + +static const struct pinctrl_ops cy8c95x0_pinctrl_ops = { + .get_groups_count = cy8c95x0_pinctrl_get_groups_count, + .get_group_name = cy8c95x0_pinctrl_get_group_name, + .get_group_pins = cy8c95x0_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinconf_generic_dt_free_map, +}; + +static int cy8c95x0_get_functions_count(struct pinctrl_dev *pctldev) +{ + return 2; +} + +static const char *cy8c95x0_get_fname(struct pinctrl_dev *pctldev, unsigned int selector) +{ + if (selector == 0) + return "gpio"; + else + return "pwm"; +} + +static int cy8c95x0_get_groups(struct pinctrl_dev *pctldev, unsigned int selector, + const char * const **groups, + unsigned int * const num_groups) +{ + struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); + + *groups = cy8c95x0_groups; + *num_groups = chip->tpin; + return 0; +} + +static int cy8c95x0_pinmux_cfg(struct cy8c95x0_pinctrl *chip, + unsigned int val, + unsigned long off) +{ + u8 port = cypress_get_port(chip, off); + u8 bit = cypress_get_pin_mask(chip, off); + int ret; + + /* select port */ + ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); + if (ret < 0) + return ret; + + ret = regmap_write_bits(chip->regmap, CY8C95X0_PWMSEL, bit, val ? bit : 0); + if (ret < 0) + return ret; + + /* Set direction to output & set output to 1 so that PWM can work */ + ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, bit); + if (ret < 0) + return ret; + + return regmap_write_bits(chip->regmap, CY8C95X0_OUTPUT_(port), bit, bit); +} + +static int cy8c95x0_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, + unsigned int group) +{ + struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); + + if (group >= chip->tpin) + return -EINVAL; + + return cy8c95x0_pinmux_cfg(chip, selector, group); +} + +static const struct pinmux_ops cy8c95x0_pmxops = { + .get_functions_count = cy8c95x0_get_functions_count, + .get_function_name = cy8c95x0_get_fname, + .get_function_groups = cy8c95x0_get_groups, + .set_mux = cy8c95x0_set_mux, + .strict = true, +}; + +static int cy8c95x0_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); + + return cy8c95x0_gpio_get_pincfg(chip, pin, config); +} + +static int cy8c95x0_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); + int ret = 0; + int i; + + if (WARN_ON(pin >= chip->tpin)) + return -EINVAL; + + for (i = 0; i < num_configs; i++) { + ret = cy8c95x0_gpio_set_pincfg(chip, pin, configs[i]); + if (ret) + return ret; + } + + return ret; +} + +static const struct pinconf_ops cy8c95x0_pinconf_ops = { + .pin_config_get = cy8c95x0_pinconf_get, + .pin_config_set = cy8c95x0_pinconf_set, + .is_generic = true, +}; + +static int cy8c95x0_irq_setup(struct cy8c95x0_pinctrl *chip, int irq) +{ + struct irq_chip *irq_chip = &chip->irq_chip; + struct gpio_irq_chip *girq = &chip->gpio_chip.irq; + DECLARE_BITMAP(pending_irqs, MAX_LINE); + int ret; + + mutex_init(&chip->irq_lock); + + bitmap_zero(pending_irqs, MAX_LINE); + + /* Read IRQ status register to clear all pending interrupts */ + ret = cy8c95x0_irq_pending(chip, pending_irqs); + if (ret) { + dev_err(chip->dev, "failed to clear irq status register\n"); + return ret; + } + + /* Mask all interrupts */ + bitmap_fill(chip->irq_mask, MAX_LINE); + + irq_chip->name = devm_kasprintf(chip->dev, GFP_KERNEL, "%s-irq", chip->name); + irq_chip->irq_mask = cy8c95x0_irq_mask; + irq_chip->irq_unmask = cy8c95x0_irq_unmask; + irq_chip->irq_bus_lock = cy8c95x0_irq_bus_lock; + irq_chip->irq_bus_sync_unlock = cy8c95x0_irq_bus_sync_unlock; + irq_chip->irq_set_type = cy8c95x0_irq_set_type; + irq_chip->irq_shutdown = cy8c95x0_irq_shutdown; + + girq->chip = irq_chip; + /* This will let us handle the parent IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_simple_irq; + girq->threaded = true; + girq->first = 0; + + ret = devm_request_threaded_irq(chip->dev, irq, + NULL, cy8c95x0_irq_handler, + IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_HIGH, + dev_name(chip->dev), chip); + if (ret) { + dev_err(chip->dev, "failed to request irq %d\n", irq); + return ret; + } + dev_info(chip->dev, "Registered threaded IRQ\n"); + + return 0; +} + +static int cy8c95x0_setup_pinctrl(struct cy8c95x0_pinctrl *chip) +{ + struct pinctrl_desc *pd = &chip->pinctrl_desc; + + pd->pctlops = &cy8c95x0_pinctrl_ops; + pd->confops = &cy8c95x0_pinconf_ops; + pd->pmxops = &cy8c95x0_pmxops; + pd->npins = chip->gpio_chip.ngpio; + pd->name = devm_kasprintf(chip->dev, GFP_KERNEL, "pinctrl-%s", + chip->name); + pd->pins = cy8c9560_pins; + pd->npins = chip->tpin; + pd->owner = THIS_MODULE; + chip->pctldev = devm_pinctrl_register(chip->dev, pd, chip); + + if (IS_ERR(chip->pctldev)) + return dev_err_probe(chip->dev, PTR_ERR(chip->pctldev), + "can't register controller\n"); + return 0; +} + +static int device_cy8c95x0_init(struct cy8c95x0_pinctrl *chip) +{ + DECLARE_BITMAP(ones, MAX_LINE); + DECLARE_BITMAP(zeros, MAX_LINE); + int ret; + + /* Set all pins to input. This is the POR default. */ + bitmap_fill(ones, MAX_LINE); + ret = cy8c95x0_write_regs_mask(chip, CY8C95X0_DIRECTION, ones, ones); + if (ret) { + dev_err(chip->dev, "Failed to set pins to input\n"); + return ret; + } + + bitmap_zero(zeros, MAX_LINE); + ret = cy8c95x0_write_regs_mask(chip, CY8C95X0_INVERT, zeros, ones); + if (ret) { + dev_err(chip->dev, "Failed to set polarity inversion\n"); + return ret; + } + + return 0; +} + +static int cy8c95x0_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + int ret; + const char *name; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + ret = i2c_smbus_read_byte_data(client, CY8C95X0_DEVID); + if (ret < 0) + return ret; + switch (ret & 0xf0) { + case 0x20: + name = cy8c95x0_id[0].name; + break; + case 0x40: + name = cy8c95x0_id[1].name; + break; + case 0x60: + name = cy8c95x0_id[2].name; + break; + default: + return -ENODEV; + } + + dev_info(&client->dev, "Found a %s chip at 0x%02x.\n", name, client->addr); + strscpy(info->type, name, I2C_NAME_SIZE); + + return -ENODEV; +} + +static int cy8c95x0_probe(struct i2c_client *client) +{ + struct cy8c95x0_pinctrl *chip; + struct regulator *reg; + int ret; + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->dev = &client->dev; + + /* Set the device type */ + if (client->dev.of_node) + chip->driver_data = (unsigned long)of_device_get_match_data(&client->dev); + else + chip->driver_data = i2c_match_id(cy8c95x0_id, client)->driver_data; + + if (!chip->driver_data) + return -ENODEV; + + i2c_set_clientdata(client, chip); + + chip->tpin = chip->driver_data & CY8C95X0_GPIO_MASK; + chip->nport = DIV_ROUND_UP(CY8C95X0_PIN_TO_OFFSET(chip->tpin), BANK_SZ); + + switch (chip->tpin) { + case 20: + strscpy(chip->name, cy8c95x0_id[0].name, I2C_NAME_SIZE); + break; + case 40: + strscpy(chip->name, cy8c95x0_id[1].name, I2C_NAME_SIZE); + break; + case 60: + strscpy(chip->name, cy8c95x0_id[2].name, I2C_NAME_SIZE); + break; + } + + reg = devm_regulator_get(&client->dev, "vdd"); + if (IS_ERR(reg)) { + if (PTR_ERR(reg) == -EPROBE_DEFER) + return -EPROBE_DEFER; + } else { + ret = regulator_enable(reg); + if (ret) { + dev_err(&client->dev, "failed to enable regulator vdd: %d\n", ret); + return ret; + } + chip->regulator = reg; + } + + chip->regmap = devm_regmap_init_i2c(client, &cy8c95x0_i2c_regmap); + if (IS_ERR(chip->regmap)) { + ret = PTR_ERR(chip->regmap); + goto err_exit; + } + + bitmap_zero(chip->push_pull, MAX_LINE); + bitmap_zero(chip->shiftmask, MAX_LINE); + bitmap_set(chip->shiftmask, 0, 20); + mutex_init(&chip->i2c_lock); + + ret = device_cy8c95x0_init(chip); + if (ret) + goto err_exit; + + if (client->irq) { + ret = cy8c95x0_irq_setup(chip, client->irq); + if (ret) + goto err_exit; + } + + ret = cy8c95x0_setup_gpiochip(chip, chip->tpin); + if (ret) + goto err_exit; + + ret = cy8c95x0_setup_pinctrl(chip); + if (ret) + goto err_exit; + + return 0; + +err_exit: + if (!IS_ERR_OR_NULL(chip->regulator)) + regulator_disable(chip->regulator); + return ret; +} + +static int cy8c95x0_remove(struct i2c_client *client) +{ + struct cy8c95x0_pinctrl *chip = i2c_get_clientdata(client); + + if (!IS_ERR_OR_NULL(chip->regulator)) + regulator_disable(chip->regulator); + + return 0; +} + +static struct i2c_driver cy8c95x0_driver = { + .driver = { + .name = "cy8c95x0-pinctrl", + .of_match_table = cy8c95x0_dt_ids, + }, + .probe_new = cy8c95x0_probe, + .remove = cy8c95x0_remove, + .id_table = cy8c95x0_id, + .detect = cy8c95x0_detect, +}; + +module_i2c_driver(cy8c95x0_driver); + +MODULE_AUTHOR("Patrick Rudolph "); +MODULE_AUTHOR("Naresh Solanki "); +MODULE_DESCRIPTION("Pinctrl driver for CY8C95X0"); +MODULE_LICENSE("GPL"); From 658aea35ab88deca19705413199933c2cef9bac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 24 Aug 2022 13:21:24 +0200 Subject: [PATCH 053/401] PCI: pci-bridge-emul: Set position of PCI capabilities to real HW value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mvebu and aardvark HW have PCIe capabilities on different offset in PCI config space. Extend pci-bridge-emul.c code to allow setting custom driver custom value where PCIe capabilities starts. With this change PCIe capabilities of both drivers are reported at the same location as where they are reported by U-Boot - in their real HW offset. Link: https://lore.kernel.org/r/20220824112124.21675-1-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/pci-aardvark.c | 1 + drivers/pci/controller/pci-mvebu.c | 1 + drivers/pci/pci-bridge-emul.c | 48 +++++++++++++++++---------- drivers/pci/pci-bridge-emul.h | 2 ++ 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 966c8b48bd96..4834198cc86b 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -1078,6 +1078,7 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS); bridge->has_pcie = true; + bridge->pcie_start = PCIE_CORE_PCIEXP_CAP; bridge->data = pcie; bridge->ops = &advk_pci_bridge_emul_ops; diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index af915c951f06..0fdbb5585fec 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c @@ -946,6 +946,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) bridge->subsystem_vendor_id = ssdev_id & 0xffff; bridge->subsystem_id = ssdev_id >> 16; bridge->has_pcie = true; + bridge->pcie_start = PCIE_CAP_PCIEXP; bridge->data = port; bridge->ops = &mvebu_pci_bridge_emul_ops; diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c index 9c2ca28e3ecf..9334b2dd4764 100644 --- a/drivers/pci/pci-bridge-emul.c +++ b/drivers/pci/pci-bridge-emul.c @@ -22,11 +22,7 @@ #define PCI_BRIDGE_CONF_END PCI_STD_HEADER_SIZEOF #define PCI_CAP_SSID_SIZEOF (PCI_SSVID_DEVICE_ID + 2) -#define PCI_CAP_SSID_START PCI_BRIDGE_CONF_END -#define PCI_CAP_SSID_END (PCI_CAP_SSID_START + PCI_CAP_SSID_SIZEOF) #define PCI_CAP_PCIE_SIZEOF (PCI_EXP_SLTSTA2 + 2) -#define PCI_CAP_PCIE_START PCI_CAP_SSID_END -#define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_CAP_PCIE_SIZEOF) /** * struct pci_bridge_reg_behavior - register bits behaviors @@ -324,7 +320,7 @@ pci_bridge_emul_read_ssid(struct pci_bridge_emul *bridge, int reg, u32 *value) switch (reg) { case PCI_CAP_LIST_ID: *value = PCI_CAP_ID_SSVID | - (bridge->has_pcie ? (PCI_CAP_PCIE_START << 8) : 0); + ((bridge->pcie_start > bridge->ssid_start) ? (bridge->pcie_start << 8) : 0); return PCI_BRIDGE_EMUL_HANDLED; case PCI_SSVID_VENDOR_ID: @@ -365,18 +361,33 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge, if (!bridge->pci_regs_behavior) return -ENOMEM; - if (bridge->subsystem_vendor_id) - bridge->conf.capabilities_pointer = PCI_CAP_SSID_START; - else if (bridge->has_pcie) - bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START; - else - bridge->conf.capabilities_pointer = 0; + /* If ssid_start and pcie_start were not specified then choose the lowest possible value. */ + if (!bridge->ssid_start && !bridge->pcie_start) { + if (bridge->subsystem_vendor_id) + bridge->ssid_start = PCI_BRIDGE_CONF_END; + if (bridge->has_pcie) + bridge->pcie_start = bridge->ssid_start + PCI_CAP_SSID_SIZEOF; + } else if (!bridge->ssid_start && bridge->subsystem_vendor_id) { + if (bridge->pcie_start - PCI_BRIDGE_CONF_END >= PCI_CAP_SSID_SIZEOF) + bridge->ssid_start = PCI_BRIDGE_CONF_END; + else + bridge->ssid_start = bridge->pcie_start + PCI_CAP_PCIE_SIZEOF; + } else if (!bridge->pcie_start && bridge->has_pcie) { + if (bridge->ssid_start - PCI_BRIDGE_CONF_END >= PCI_CAP_PCIE_SIZEOF) + bridge->pcie_start = PCI_BRIDGE_CONF_END; + else + bridge->pcie_start = bridge->ssid_start + PCI_CAP_SSID_SIZEOF; + } + + bridge->conf.capabilities_pointer = min(bridge->ssid_start, bridge->pcie_start); if (bridge->conf.capabilities_pointer) bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST); if (bridge->has_pcie) { bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP; + bridge->pcie_conf.next = (bridge->ssid_start > bridge->pcie_start) ? + bridge->ssid_start : 0; bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4); bridge->pcie_cap_regs_behavior = kmemdup(pcie_cap_regs_behavior, @@ -459,15 +470,17 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, read_op = bridge->ops->read_base; cfgspace = (__le32 *) &bridge->conf; behavior = bridge->pci_regs_behavior; - } else if (reg >= PCI_CAP_SSID_START && reg < PCI_CAP_SSID_END && bridge->subsystem_vendor_id) { + } else if (reg >= bridge->ssid_start && reg < bridge->ssid_start + PCI_CAP_SSID_SIZEOF && + bridge->subsystem_vendor_id) { /* Emulated PCI Bridge Subsystem Vendor ID capability */ - reg -= PCI_CAP_SSID_START; + reg -= bridge->ssid_start; read_op = pci_bridge_emul_read_ssid; cfgspace = NULL; behavior = NULL; - } else if (reg >= PCI_CAP_PCIE_START && reg < PCI_CAP_PCIE_END && bridge->has_pcie) { + } else if (reg >= bridge->pcie_start && reg < bridge->pcie_start + PCI_CAP_PCIE_SIZEOF && + bridge->has_pcie) { /* Our emulated PCIe capability */ - reg -= PCI_CAP_PCIE_START; + reg -= bridge->pcie_start; read_op = bridge->ops->read_pcie; cfgspace = (__le32 *) &bridge->pcie_conf; behavior = bridge->pcie_cap_regs_behavior; @@ -538,9 +551,10 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, write_op = bridge->ops->write_base; cfgspace = (__le32 *) &bridge->conf; behavior = bridge->pci_regs_behavior; - } else if (reg >= PCI_CAP_PCIE_START && reg < PCI_CAP_PCIE_END && bridge->has_pcie) { + } else if (reg >= bridge->pcie_start && reg < bridge->pcie_start + PCI_CAP_PCIE_SIZEOF && + bridge->has_pcie) { /* Our emulated PCIe capability */ - reg -= PCI_CAP_PCIE_START; + reg -= bridge->pcie_start; write_op = bridge->ops->write_pcie; cfgspace = (__le32 *) &bridge->pcie_conf; behavior = bridge->pcie_cap_regs_behavior; diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h index 71392b67471d..2a0e59c7f0d9 100644 --- a/drivers/pci/pci-bridge-emul.h +++ b/drivers/pci/pci-bridge-emul.h @@ -131,6 +131,8 @@ struct pci_bridge_emul { struct pci_bridge_reg_behavior *pci_regs_behavior; struct pci_bridge_reg_behavior *pcie_cap_regs_behavior; void *data; + u8 pcie_start; + u8 ssid_start; bool has_pcie; u16 subsystem_vendor_id; u16 subsystem_id; From 0e3db16300fbae5e47ce6c298bf63a7862e5d576 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 20 Jun 2022 19:50:53 +0300 Subject: [PATCH 054/401] pinctrl: bcm: Convert drivers to use struct pingroup and PINCTRL_PINGROUP() The pin control header provides struct pingroup and PINCTRL_PINGROUP() macro. Utilize them instead of open coded variants in the driver. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220620165053.74170-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm6318.c | 121 ++++++++++----------- drivers/pinctrl/bcm/pinctrl-bcm63268.c | 139 +++++++++++-------------- drivers/pinctrl/bcm/pinctrl-bcm6328.c | 83 +++++++-------- drivers/pinctrl/bcm/pinctrl-bcm6358.c | 20 ++-- drivers/pinctrl/bcm/pinctrl-bcm6362.c | 121 ++++++++++----------- drivers/pinctrl/bcm/pinctrl-bcm6368.c | 91 +++++++--------- drivers/pinctrl/bcm/pinctrl-bcm63xx.h | 2 + 7 files changed, 258 insertions(+), 319 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6318.c b/drivers/pinctrl/bcm/pinctrl-bcm6318.c index 9311220fb6cb..64073546310e 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm6318.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm6318.c @@ -27,12 +27,6 @@ #define BCM6318_PAD_REG 0x54 #define BCM6328_PAD_MASK GENMASK(3, 0) -struct bcm6318_pingroup { - const char *name; - const unsigned * const pins; - const unsigned num_pins; -}; - struct bcm6318_function { const char *name; const char * const *groups; @@ -146,64 +140,57 @@ static unsigned gpio47_pins[] = { 47 }; static unsigned gpio48_pins[] = { 48 }; static unsigned gpio49_pins[] = { 49 }; -#define BCM6318_GROUP(n) \ - { \ - .name = #n, \ - .pins = n##_pins, \ - .num_pins = ARRAY_SIZE(n##_pins), \ - } - -static struct bcm6318_pingroup bcm6318_groups[] = { - BCM6318_GROUP(gpio0), - BCM6318_GROUP(gpio1), - BCM6318_GROUP(gpio2), - BCM6318_GROUP(gpio3), - BCM6318_GROUP(gpio4), - BCM6318_GROUP(gpio5), - BCM6318_GROUP(gpio6), - BCM6318_GROUP(gpio7), - BCM6318_GROUP(gpio8), - BCM6318_GROUP(gpio9), - BCM6318_GROUP(gpio10), - BCM6318_GROUP(gpio11), - BCM6318_GROUP(gpio12), - BCM6318_GROUP(gpio13), - BCM6318_GROUP(gpio14), - BCM6318_GROUP(gpio15), - BCM6318_GROUP(gpio16), - BCM6318_GROUP(gpio17), - BCM6318_GROUP(gpio18), - BCM6318_GROUP(gpio19), - BCM6318_GROUP(gpio20), - BCM6318_GROUP(gpio21), - BCM6318_GROUP(gpio22), - BCM6318_GROUP(gpio23), - BCM6318_GROUP(gpio24), - BCM6318_GROUP(gpio25), - BCM6318_GROUP(gpio26), - BCM6318_GROUP(gpio27), - BCM6318_GROUP(gpio28), - BCM6318_GROUP(gpio29), - BCM6318_GROUP(gpio30), - BCM6318_GROUP(gpio31), - BCM6318_GROUP(gpio32), - BCM6318_GROUP(gpio33), - BCM6318_GROUP(gpio34), - BCM6318_GROUP(gpio35), - BCM6318_GROUP(gpio36), - BCM6318_GROUP(gpio37), - BCM6318_GROUP(gpio38), - BCM6318_GROUP(gpio39), - BCM6318_GROUP(gpio40), - BCM6318_GROUP(gpio41), - BCM6318_GROUP(gpio42), - BCM6318_GROUP(gpio43), - BCM6318_GROUP(gpio44), - BCM6318_GROUP(gpio45), - BCM6318_GROUP(gpio46), - BCM6318_GROUP(gpio47), - BCM6318_GROUP(gpio48), - BCM6318_GROUP(gpio49), +static struct pingroup bcm6318_groups[] = { + BCM_PIN_GROUP(gpio0), + BCM_PIN_GROUP(gpio1), + BCM_PIN_GROUP(gpio2), + BCM_PIN_GROUP(gpio3), + BCM_PIN_GROUP(gpio4), + BCM_PIN_GROUP(gpio5), + BCM_PIN_GROUP(gpio6), + BCM_PIN_GROUP(gpio7), + BCM_PIN_GROUP(gpio8), + BCM_PIN_GROUP(gpio9), + BCM_PIN_GROUP(gpio10), + BCM_PIN_GROUP(gpio11), + BCM_PIN_GROUP(gpio12), + BCM_PIN_GROUP(gpio13), + BCM_PIN_GROUP(gpio14), + BCM_PIN_GROUP(gpio15), + BCM_PIN_GROUP(gpio16), + BCM_PIN_GROUP(gpio17), + BCM_PIN_GROUP(gpio18), + BCM_PIN_GROUP(gpio19), + BCM_PIN_GROUP(gpio20), + BCM_PIN_GROUP(gpio21), + BCM_PIN_GROUP(gpio22), + BCM_PIN_GROUP(gpio23), + BCM_PIN_GROUP(gpio24), + BCM_PIN_GROUP(gpio25), + BCM_PIN_GROUP(gpio26), + BCM_PIN_GROUP(gpio27), + BCM_PIN_GROUP(gpio28), + BCM_PIN_GROUP(gpio29), + BCM_PIN_GROUP(gpio30), + BCM_PIN_GROUP(gpio31), + BCM_PIN_GROUP(gpio32), + BCM_PIN_GROUP(gpio33), + BCM_PIN_GROUP(gpio34), + BCM_PIN_GROUP(gpio35), + BCM_PIN_GROUP(gpio36), + BCM_PIN_GROUP(gpio37), + BCM_PIN_GROUP(gpio38), + BCM_PIN_GROUP(gpio39), + BCM_PIN_GROUP(gpio40), + BCM_PIN_GROUP(gpio41), + BCM_PIN_GROUP(gpio42), + BCM_PIN_GROUP(gpio43), + BCM_PIN_GROUP(gpio44), + BCM_PIN_GROUP(gpio45), + BCM_PIN_GROUP(gpio46), + BCM_PIN_GROUP(gpio47), + BCM_PIN_GROUP(gpio48), + BCM_PIN_GROUP(gpio49), }; /* GPIO_MODE */ @@ -368,10 +355,10 @@ static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev, static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, const unsigned **pins, - unsigned *num_pins) + unsigned *npins) { *pins = bcm6318_groups[group].pins; - *num_pins = bcm6318_groups[group].num_pins; + *npins = bcm6318_groups[group].npins; return 0; } @@ -424,7 +411,7 @@ static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); - const struct bcm6318_pingroup *pg = &bcm6318_groups[group]; + const struct pingroup *pg = &bcm6318_groups[group]; const struct bcm6318_function *f = &bcm6318_funcs[selector]; bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63268.c b/drivers/pinctrl/bcm/pinctrl-bcm63268.c index 1c1060a39597..80c2fc55ffa2 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm63268.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c @@ -40,12 +40,6 @@ enum bcm63268_pinctrl_reg { BCM63268_BASEMODE, }; -struct bcm63268_pingroup { - const char *name; - const unsigned * const pins; - const unsigned num_pins; -}; - struct bcm63268_function { const char *name; const char * const *groups; @@ -185,74 +179,67 @@ static unsigned vdsl_phy1_grp_pins[] = { 12, 13 }; static unsigned vdsl_phy2_grp_pins[] = { 24, 25 }; static unsigned vdsl_phy3_grp_pins[] = { 26, 27 }; -#define BCM63268_GROUP(n) \ - { \ - .name = #n, \ - .pins = n##_pins, \ - .num_pins = ARRAY_SIZE(n##_pins), \ - } - -static struct bcm63268_pingroup bcm63268_groups[] = { - BCM63268_GROUP(gpio0), - BCM63268_GROUP(gpio1), - BCM63268_GROUP(gpio2), - BCM63268_GROUP(gpio3), - BCM63268_GROUP(gpio4), - BCM63268_GROUP(gpio5), - BCM63268_GROUP(gpio6), - BCM63268_GROUP(gpio7), - BCM63268_GROUP(gpio8), - BCM63268_GROUP(gpio9), - BCM63268_GROUP(gpio10), - BCM63268_GROUP(gpio11), - BCM63268_GROUP(gpio12), - BCM63268_GROUP(gpio13), - BCM63268_GROUP(gpio14), - BCM63268_GROUP(gpio15), - BCM63268_GROUP(gpio16), - BCM63268_GROUP(gpio17), - BCM63268_GROUP(gpio18), - BCM63268_GROUP(gpio19), - BCM63268_GROUP(gpio20), - BCM63268_GROUP(gpio21), - BCM63268_GROUP(gpio22), - BCM63268_GROUP(gpio23), - BCM63268_GROUP(gpio24), - BCM63268_GROUP(gpio25), - BCM63268_GROUP(gpio26), - BCM63268_GROUP(gpio27), - BCM63268_GROUP(gpio28), - BCM63268_GROUP(gpio29), - BCM63268_GROUP(gpio30), - BCM63268_GROUP(gpio31), - BCM63268_GROUP(gpio32), - BCM63268_GROUP(gpio33), - BCM63268_GROUP(gpio34), - BCM63268_GROUP(gpio35), - BCM63268_GROUP(gpio36), - BCM63268_GROUP(gpio37), - BCM63268_GROUP(gpio38), - BCM63268_GROUP(gpio39), - BCM63268_GROUP(gpio40), - BCM63268_GROUP(gpio41), - BCM63268_GROUP(gpio42), - BCM63268_GROUP(gpio43), - BCM63268_GROUP(gpio44), - BCM63268_GROUP(gpio45), - BCM63268_GROUP(gpio46), - BCM63268_GROUP(gpio47), - BCM63268_GROUP(gpio48), - BCM63268_GROUP(gpio49), - BCM63268_GROUP(gpio50), - BCM63268_GROUP(gpio51), +static struct pingroup bcm63268_groups[] = { + BCM_PIN_GROUP(gpio0), + BCM_PIN_GROUP(gpio1), + BCM_PIN_GROUP(gpio2), + BCM_PIN_GROUP(gpio3), + BCM_PIN_GROUP(gpio4), + BCM_PIN_GROUP(gpio5), + BCM_PIN_GROUP(gpio6), + BCM_PIN_GROUP(gpio7), + BCM_PIN_GROUP(gpio8), + BCM_PIN_GROUP(gpio9), + BCM_PIN_GROUP(gpio10), + BCM_PIN_GROUP(gpio11), + BCM_PIN_GROUP(gpio12), + BCM_PIN_GROUP(gpio13), + BCM_PIN_GROUP(gpio14), + BCM_PIN_GROUP(gpio15), + BCM_PIN_GROUP(gpio16), + BCM_PIN_GROUP(gpio17), + BCM_PIN_GROUP(gpio18), + BCM_PIN_GROUP(gpio19), + BCM_PIN_GROUP(gpio20), + BCM_PIN_GROUP(gpio21), + BCM_PIN_GROUP(gpio22), + BCM_PIN_GROUP(gpio23), + BCM_PIN_GROUP(gpio24), + BCM_PIN_GROUP(gpio25), + BCM_PIN_GROUP(gpio26), + BCM_PIN_GROUP(gpio27), + BCM_PIN_GROUP(gpio28), + BCM_PIN_GROUP(gpio29), + BCM_PIN_GROUP(gpio30), + BCM_PIN_GROUP(gpio31), + BCM_PIN_GROUP(gpio32), + BCM_PIN_GROUP(gpio33), + BCM_PIN_GROUP(gpio34), + BCM_PIN_GROUP(gpio35), + BCM_PIN_GROUP(gpio36), + BCM_PIN_GROUP(gpio37), + BCM_PIN_GROUP(gpio38), + BCM_PIN_GROUP(gpio39), + BCM_PIN_GROUP(gpio40), + BCM_PIN_GROUP(gpio41), + BCM_PIN_GROUP(gpio42), + BCM_PIN_GROUP(gpio43), + BCM_PIN_GROUP(gpio44), + BCM_PIN_GROUP(gpio45), + BCM_PIN_GROUP(gpio46), + BCM_PIN_GROUP(gpio47), + BCM_PIN_GROUP(gpio48), + BCM_PIN_GROUP(gpio49), + BCM_PIN_GROUP(gpio50), + BCM_PIN_GROUP(gpio51), /* multi pin groups */ - BCM63268_GROUP(nand_grp), - BCM63268_GROUP(dectpd_grp), - BCM63268_GROUP(vdsl_phy0_grp), - BCM63268_GROUP(vdsl_phy1_grp), - BCM63268_GROUP(vdsl_phy2_grp), - BCM63268_GROUP(vdsl_phy3_grp), + BCM_PIN_GROUP(nand_grp), + BCM_PIN_GROUP(dectpd_grp), + BCM_PIN_GROUP(vdsl_phy0_grp), + BCM_PIN_GROUP(vdsl_phy1_grp), + BCM_PIN_GROUP(vdsl_phy2_grp), + BCM_PIN_GROUP(vdsl_phy3_grp), }; static const char * const led_groups[] = { @@ -487,10 +474,10 @@ static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev, static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, const unsigned **pins, - unsigned *num_pins) + unsigned *npins) { *pins = bcm63268_groups[group].pins; - *num_pins = bcm63268_groups[group].num_pins; + *npins = bcm63268_groups[group].npins; return 0; } @@ -545,13 +532,13 @@ static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); - const struct bcm63268_pingroup *pg = &bcm63268_groups[group]; + const struct pingroup *pg = &bcm63268_groups[group]; const struct bcm63268_function *f = &bcm63268_funcs[selector]; unsigned i; unsigned int reg; unsigned int val, mask; - for (i = 0; i < pg->num_pins; i++) + for (i = 0; i < pg->npins; i++) bcm63268_set_gpio(pc, pg->pins[i]); switch (f->reg) { diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6328.c b/drivers/pinctrl/bcm/pinctrl-bcm6328.c index ffa8864abab6..1eef5ab9a5e5 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm6328.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c @@ -125,49 +125,42 @@ static unsigned gpio31_pins[] = { 31 }; static unsigned hsspi_cs1_pins[] = { 36 }; static unsigned usb_port1_pins[] = { 38 }; -#define BCM6328_GROUP(n) \ - { \ - .name = #n, \ - .pins = n##_pins, \ - .num_pins = ARRAY_SIZE(n##_pins), \ - } +static struct pingroup bcm6328_groups[] = { + BCM_PIN_GROUP(gpio0), + BCM_PIN_GROUP(gpio1), + BCM_PIN_GROUP(gpio2), + BCM_PIN_GROUP(gpio3), + BCM_PIN_GROUP(gpio4), + BCM_PIN_GROUP(gpio5), + BCM_PIN_GROUP(gpio6), + BCM_PIN_GROUP(gpio7), + BCM_PIN_GROUP(gpio8), + BCM_PIN_GROUP(gpio9), + BCM_PIN_GROUP(gpio10), + BCM_PIN_GROUP(gpio11), + BCM_PIN_GROUP(gpio12), + BCM_PIN_GROUP(gpio13), + BCM_PIN_GROUP(gpio14), + BCM_PIN_GROUP(gpio15), + BCM_PIN_GROUP(gpio16), + BCM_PIN_GROUP(gpio17), + BCM_PIN_GROUP(gpio18), + BCM_PIN_GROUP(gpio19), + BCM_PIN_GROUP(gpio20), + BCM_PIN_GROUP(gpio21), + BCM_PIN_GROUP(gpio22), + BCM_PIN_GROUP(gpio23), + BCM_PIN_GROUP(gpio24), + BCM_PIN_GROUP(gpio25), + BCM_PIN_GROUP(gpio26), + BCM_PIN_GROUP(gpio27), + BCM_PIN_GROUP(gpio28), + BCM_PIN_GROUP(gpio29), + BCM_PIN_GROUP(gpio30), + BCM_PIN_GROUP(gpio31), -static struct bcm6328_pingroup bcm6328_groups[] = { - BCM6328_GROUP(gpio0), - BCM6328_GROUP(gpio1), - BCM6328_GROUP(gpio2), - BCM6328_GROUP(gpio3), - BCM6328_GROUP(gpio4), - BCM6328_GROUP(gpio5), - BCM6328_GROUP(gpio6), - BCM6328_GROUP(gpio7), - BCM6328_GROUP(gpio8), - BCM6328_GROUP(gpio9), - BCM6328_GROUP(gpio10), - BCM6328_GROUP(gpio11), - BCM6328_GROUP(gpio12), - BCM6328_GROUP(gpio13), - BCM6328_GROUP(gpio14), - BCM6328_GROUP(gpio15), - BCM6328_GROUP(gpio16), - BCM6328_GROUP(gpio17), - BCM6328_GROUP(gpio18), - BCM6328_GROUP(gpio19), - BCM6328_GROUP(gpio20), - BCM6328_GROUP(gpio21), - BCM6328_GROUP(gpio22), - BCM6328_GROUP(gpio23), - BCM6328_GROUP(gpio24), - BCM6328_GROUP(gpio25), - BCM6328_GROUP(gpio26), - BCM6328_GROUP(gpio27), - BCM6328_GROUP(gpio28), - BCM6328_GROUP(gpio29), - BCM6328_GROUP(gpio30), - BCM6328_GROUP(gpio31), - - BCM6328_GROUP(hsspi_cs1), - BCM6328_GROUP(usb_port1), + BCM_PIN_GROUP(hsspi_cs1), + BCM_PIN_GROUP(usb_port1), }; /* GPIO_MODE */ @@ -292,10 +285,10 @@ static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev, static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, const unsigned **pins, - unsigned *num_pins) + unsigned *npins) { *pins = bcm6328_groups[group].pins; - *num_pins = bcm6328_groups[group].num_pins; + *npins = bcm6328_groups[group].npins; return 0; } @@ -338,7 +331,7 @@ static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); - const struct bcm6328_pingroup *pg = &bcm6328_groups[group]; + const struct pingroup *pg = &bcm6328_groups[group]; const struct bcm6328_function *f = &bcm6328_funcs[selector]; bcm6328_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6358.c b/drivers/pinctrl/bcm/pinctrl-bcm6358.c index 9f6cd7447887..891de49d76e7 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm6358.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm6358.c @@ -35,9 +35,7 @@ #define BCM6358_MODE_MUX_SYS_IRQ BIT(15) struct bcm6358_pingroup { - const char *name; - const unsigned * const pins; - const unsigned num_pins; + struct pingroup grp; const uint16_t mode_val; @@ -131,9 +129,7 @@ static unsigned sys_irq_grp_pins[] = { 5 }; #define BCM6358_GPIO_MUX_GROUP(n, bit, dir) \ { \ - .name = #n, \ - .pins = n##_pins, \ - .num_pins = ARRAY_SIZE(n##_pins), \ + .grp = BCM_PIN_GROUP(n), \ .mode_val = BCM6358_MODE_MUX_##bit, \ .direction = dir, \ } @@ -219,15 +215,15 @@ static int bcm6358_pinctrl_get_group_count(struct pinctrl_dev *pctldev) static const char *bcm6358_pinctrl_get_group_name(struct pinctrl_dev *pctldev, unsigned group) { - return bcm6358_groups[group].name; + return bcm6358_groups[group].grp.name; } static int bcm6358_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, const unsigned **pins, - unsigned *num_pins) + unsigned *npins) { - *pins = bcm6358_groups[group].pins; - *num_pins = bcm6358_groups[group].num_pins; + *pins = bcm6358_groups[group].grp.pins; + *npins = bcm6358_groups[group].grp.npins; return 0; } @@ -264,12 +260,12 @@ static int bcm6358_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned int mask = val; unsigned pin; - for (pin = 0; pin < pg->num_pins; pin++) + for (pin = 0; pin < pg->grp.npins; pin++) mask |= (unsigned long)bcm6358_pins[pin].drv_data; regmap_field_update_bits(priv->overlays, mask, val); - for (pin = 0; pin < pg->num_pins; pin++) { + for (pin = 0; pin < pg->grp.npins; pin++) { struct pinctrl_gpio_range *range; unsigned int hw_gpio = bcm6358_pins[pin].number; diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6362.c b/drivers/pinctrl/bcm/pinctrl-bcm6362.c index 13c7230949b2..d9ba1b6c2aeb 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm6362.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm6362.c @@ -35,12 +35,6 @@ enum bcm6362_pinctrl_reg { BCM6362_BASEMODE, }; -struct bcm6362_pingroup { - const char *name; - const unsigned * const pins; - const unsigned num_pins; -}; - struct bcm6362_function { const char *name; const char * const *groups; @@ -162,63 +156,56 @@ static unsigned nand_grp_pins[] = { 18, 19, 20, 21, 22, 23, 27, }; -#define BCM6362_GROUP(n) \ - { \ - .name = #n, \ - .pins = n##_pins, \ - .num_pins = ARRAY_SIZE(n##_pins), \ - } - -static struct bcm6362_pingroup bcm6362_groups[] = { - BCM6362_GROUP(gpio0), - BCM6362_GROUP(gpio1), - BCM6362_GROUP(gpio2), - BCM6362_GROUP(gpio3), - BCM6362_GROUP(gpio4), - BCM6362_GROUP(gpio5), - BCM6362_GROUP(gpio6), - BCM6362_GROUP(gpio7), - BCM6362_GROUP(gpio8), - BCM6362_GROUP(gpio9), - BCM6362_GROUP(gpio10), - BCM6362_GROUP(gpio11), - BCM6362_GROUP(gpio12), - BCM6362_GROUP(gpio13), - BCM6362_GROUP(gpio14), - BCM6362_GROUP(gpio15), - BCM6362_GROUP(gpio16), - BCM6362_GROUP(gpio17), - BCM6362_GROUP(gpio18), - BCM6362_GROUP(gpio19), - BCM6362_GROUP(gpio20), - BCM6362_GROUP(gpio21), - BCM6362_GROUP(gpio22), - BCM6362_GROUP(gpio23), - BCM6362_GROUP(gpio24), - BCM6362_GROUP(gpio25), - BCM6362_GROUP(gpio26), - BCM6362_GROUP(gpio27), - BCM6362_GROUP(gpio28), - BCM6362_GROUP(gpio29), - BCM6362_GROUP(gpio30), - BCM6362_GROUP(gpio31), - BCM6362_GROUP(gpio32), - BCM6362_GROUP(gpio33), - BCM6362_GROUP(gpio34), - BCM6362_GROUP(gpio35), - BCM6362_GROUP(gpio36), - BCM6362_GROUP(gpio37), - BCM6362_GROUP(gpio38), - BCM6362_GROUP(gpio39), - BCM6362_GROUP(gpio40), - BCM6362_GROUP(gpio41), - BCM6362_GROUP(gpio42), - BCM6362_GROUP(gpio43), - BCM6362_GROUP(gpio44), - BCM6362_GROUP(gpio45), - BCM6362_GROUP(gpio46), - BCM6362_GROUP(gpio47), - BCM6362_GROUP(nand_grp), +static struct pingroup bcm6362_groups[] = { + BCM_PIN_GROUP(gpio0), + BCM_PIN_GROUP(gpio1), + BCM_PIN_GROUP(gpio2), + BCM_PIN_GROUP(gpio3), + BCM_PIN_GROUP(gpio4), + BCM_PIN_GROUP(gpio5), + BCM_PIN_GROUP(gpio6), + BCM_PIN_GROUP(gpio7), + BCM_PIN_GROUP(gpio8), + BCM_PIN_GROUP(gpio9), + BCM_PIN_GROUP(gpio10), + BCM_PIN_GROUP(gpio11), + BCM_PIN_GROUP(gpio12), + BCM_PIN_GROUP(gpio13), + BCM_PIN_GROUP(gpio14), + BCM_PIN_GROUP(gpio15), + BCM_PIN_GROUP(gpio16), + BCM_PIN_GROUP(gpio17), + BCM_PIN_GROUP(gpio18), + BCM_PIN_GROUP(gpio19), + BCM_PIN_GROUP(gpio20), + BCM_PIN_GROUP(gpio21), + BCM_PIN_GROUP(gpio22), + BCM_PIN_GROUP(gpio23), + BCM_PIN_GROUP(gpio24), + BCM_PIN_GROUP(gpio25), + BCM_PIN_GROUP(gpio26), + BCM_PIN_GROUP(gpio27), + BCM_PIN_GROUP(gpio28), + BCM_PIN_GROUP(gpio29), + BCM_PIN_GROUP(gpio30), + BCM_PIN_GROUP(gpio31), + BCM_PIN_GROUP(gpio32), + BCM_PIN_GROUP(gpio33), + BCM_PIN_GROUP(gpio34), + BCM_PIN_GROUP(gpio35), + BCM_PIN_GROUP(gpio36), + BCM_PIN_GROUP(gpio37), + BCM_PIN_GROUP(gpio38), + BCM_PIN_GROUP(gpio39), + BCM_PIN_GROUP(gpio40), + BCM_PIN_GROUP(gpio41), + BCM_PIN_GROUP(gpio42), + BCM_PIN_GROUP(gpio43), + BCM_PIN_GROUP(gpio44), + BCM_PIN_GROUP(gpio45), + BCM_PIN_GROUP(gpio46), + BCM_PIN_GROUP(gpio47), + BCM_PIN_GROUP(nand_grp), }; static const char * const led_groups[] = { @@ -463,10 +450,10 @@ static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev, static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, const unsigned **pins, - unsigned *num_pins) + unsigned *npins) { *pins = bcm6362_groups[group].pins; - *num_pins = bcm6362_groups[group].num_pins; + *npins = bcm6362_groups[group].npins; return 0; } @@ -519,13 +506,13 @@ static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); - const struct bcm6362_pingroup *pg = &bcm6362_groups[group]; + const struct pingroup *pg = &bcm6362_groups[group]; const struct bcm6362_function *f = &bcm6362_funcs[selector]; unsigned i; unsigned int reg; unsigned int val, mask; - for (i = 0; i < pg->num_pins; i++) + for (i = 0; i < pg->npins; i++) bcm6362_set_gpio(pc, pg->pins[i]); switch (f->reg) { diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6368.c b/drivers/pinctrl/bcm/pinctrl-bcm6368.c index b33a74aec82b..6208467ba6f9 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm6368.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm6368.c @@ -26,12 +26,6 @@ #define BCM6368_BASEMODE_GPIO 0x0 #define BCM6368_BASEMODE_UART1 0x1 -struct bcm6368_pingroup { - const char *name; - const unsigned * const pins; - const unsigned num_pins; -}; - struct bcm6368_function { const char *name; const char * const *groups; @@ -127,47 +121,40 @@ static unsigned gpio30_pins[] = { 30 }; static unsigned gpio31_pins[] = { 31 }; static unsigned uart1_grp_pins[] = { 30, 31, 32, 33 }; -#define BCM6368_GROUP(n) \ - { \ - .name = #n, \ - .pins = n##_pins, \ - .num_pins = ARRAY_SIZE(n##_pins), \ - } - -static struct bcm6368_pingroup bcm6368_groups[] = { - BCM6368_GROUP(gpio0), - BCM6368_GROUP(gpio1), - BCM6368_GROUP(gpio2), - BCM6368_GROUP(gpio3), - BCM6368_GROUP(gpio4), - BCM6368_GROUP(gpio5), - BCM6368_GROUP(gpio6), - BCM6368_GROUP(gpio7), - BCM6368_GROUP(gpio8), - BCM6368_GROUP(gpio9), - BCM6368_GROUP(gpio10), - BCM6368_GROUP(gpio11), - BCM6368_GROUP(gpio12), - BCM6368_GROUP(gpio13), - BCM6368_GROUP(gpio14), - BCM6368_GROUP(gpio15), - BCM6368_GROUP(gpio16), - BCM6368_GROUP(gpio17), - BCM6368_GROUP(gpio18), - BCM6368_GROUP(gpio19), - BCM6368_GROUP(gpio20), - BCM6368_GROUP(gpio21), - BCM6368_GROUP(gpio22), - BCM6368_GROUP(gpio23), - BCM6368_GROUP(gpio24), - BCM6368_GROUP(gpio25), - BCM6368_GROUP(gpio26), - BCM6368_GROUP(gpio27), - BCM6368_GROUP(gpio28), - BCM6368_GROUP(gpio29), - BCM6368_GROUP(gpio30), - BCM6368_GROUP(gpio31), - BCM6368_GROUP(uart1_grp), +static struct pingroup bcm6368_groups[] = { + BCM_PIN_GROUP(gpio0), + BCM_PIN_GROUP(gpio1), + BCM_PIN_GROUP(gpio2), + BCM_PIN_GROUP(gpio3), + BCM_PIN_GROUP(gpio4), + BCM_PIN_GROUP(gpio5), + BCM_PIN_GROUP(gpio6), + BCM_PIN_GROUP(gpio7), + BCM_PIN_GROUP(gpio8), + BCM_PIN_GROUP(gpio9), + BCM_PIN_GROUP(gpio10), + BCM_PIN_GROUP(gpio11), + BCM_PIN_GROUP(gpio12), + BCM_PIN_GROUP(gpio13), + BCM_PIN_GROUP(gpio14), + BCM_PIN_GROUP(gpio15), + BCM_PIN_GROUP(gpio16), + BCM_PIN_GROUP(gpio17), + BCM_PIN_GROUP(gpio18), + BCM_PIN_GROUP(gpio19), + BCM_PIN_GROUP(gpio20), + BCM_PIN_GROUP(gpio21), + BCM_PIN_GROUP(gpio22), + BCM_PIN_GROUP(gpio23), + BCM_PIN_GROUP(gpio24), + BCM_PIN_GROUP(gpio25), + BCM_PIN_GROUP(gpio26), + BCM_PIN_GROUP(gpio27), + BCM_PIN_GROUP(gpio28), + BCM_PIN_GROUP(gpio29), + BCM_PIN_GROUP(gpio30), + BCM_PIN_GROUP(gpio31), + BCM_PIN_GROUP(uart1_grp), }; static const char * const analog_afe_0_groups[] = { @@ -358,10 +345,10 @@ static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev *pctldev, static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned group, const unsigned **pins, - unsigned *num_pins) + unsigned *npins) { *pins = bcm6368_groups[group].pins; - *num_pins = bcm6368_groups[group].num_pins; + *npins = bcm6368_groups[group].npins; return 0; } @@ -393,14 +380,14 @@ static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev, { struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); struct bcm6368_priv *priv = pc->driver_data; - const struct bcm6368_pingroup *pg = &bcm6368_groups[group]; + const struct pingroup *pg = &bcm6368_groups[group]; const struct bcm6368_function *fun = &bcm6368_funcs[selector]; int i, pin; if (fun->basemode) { unsigned int mask = 0; - for (i = 0; i < pg->num_pins; i++) { + for (i = 0; i < pg->npins; i++) { pin = pg->pins[i]; if (pin < BCM63XX_BANK_GPIOS) mask |= BIT(pin); @@ -419,7 +406,7 @@ static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev, BIT(pin)); } - for (pin = 0; pin < pg->num_pins; pin++) { + for (pin = 0; pin < pg->npins; pin++) { struct pinctrl_gpio_range *range; int hw_gpio = bcm6368_pins[pin].number; diff --git a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h index d58c8cd5b6b8..95243027ecd9 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm63xx.h +++ b/drivers/pinctrl/bcm/pinctrl-bcm63xx.h @@ -21,6 +21,8 @@ struct bcm63xx_pinctrl_soc { unsigned int ngpios; }; +#define BCM_PIN_GROUP(n) PINCTRL_PINGROUP(#n, n##_pins, ARRAY_SIZE(n##_pins)) + struct bcm63xx_pinctrl { struct device *dev; struct regmap *regs; From 39b707fa7aba7cbfd7d53be50b6098e620f7a6d4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 21 Jun 2022 14:29:04 +0300 Subject: [PATCH 055/401] pinctrl: nomadik: Convert drivers to use struct pingroup and PINCTRL_PINGROUP() The pin control header provides struct pingroup and PINCTRL_PINGROUP() macro. Utilize them instead of open coded variants in the driver. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220621112904.65674-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- .../pinctrl/nomadik/pinctrl-nomadik-db8500.c | 295 +++++++++--------- .../pinctrl/nomadik/pinctrl-nomadik-stn8815.c | 29 +- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 26 +- drivers/pinctrl/nomadik/pinctrl-nomadik.h | 16 +- 4 files changed, 180 insertions(+), 186 deletions(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c index ac3d4d91266d..758d21f0a850 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c @@ -674,163 +674,160 @@ static const unsigned hwobs_oc4_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; -#define DB8500_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \ - .npins = ARRAY_SIZE(a##_pins), .altsetting = b } - static const struct nmk_pingroup nmk_db8500_groups[] = { /* Altfunction A column */ - DB8500_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(u1rxtx_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(u1ctsrts_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(ipi2c_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(ipi2c_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(msp0txrx_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(msp0tfstck_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(msp0rfsrck_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc0_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc0_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc0_dat47_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc0dat31dir_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(msp1txrx_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(msp1_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(lcdb_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(lcdvsi0_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(lcdvsi1_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(lcd_d0_d7_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(lcd_d8_d11_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(lcd_d12_d15_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(lcd_d12_d23_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(kp_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(kpskaskb_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc2_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc2_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(ssp1_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(ssp0_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(modem_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc1_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc1_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(mc1dir_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(u1rxtx_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(u1ctsrts_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(ipi2c_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(ipi2c_a_2, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(msp0txrx_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(msp0tfstck_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(msp0rfsrck_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc0_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc0_a_2, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc0_dat47_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc0dat31dir_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(msp1txrx_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(msp1_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(lcdb_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(lcdvsi0_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(lcdvsi1_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(lcd_d0_d7_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(lcd_d8_d11_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(lcd_d12_d15_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(lcd_d12_d23_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(kp_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(kpskaskb_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc2_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc2_a_2, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(ssp1_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(ssp0_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(modem_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc1_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc1_a_2, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mc1dir_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), /* Altfunction B column */ - DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(i2c4_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(i2c1_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(i2c2_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(i2c2_b_2, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(msp0txrx_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(i2c1_b_2, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(u2rxtx_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(uartmodtx_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(msp0sck_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(uartmodrx_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(stmmod_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(uartmodrx_b_2, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(kp_b_2, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(ipgpio7_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(ipgpio2_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(ipgpio3_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(lcdaclk_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(lcda_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(lcd_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(lcd_d16_d23_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(ddrtrig_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(pwl_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(spi1_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(mc3_b_1, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(pwl_b_2, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(pwl_b_3, NMK_GPIO_ALT_B), - DB8500_PIN_GROUP(pwl_b_4, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(i2c4_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(i2c1_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(i2c2_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(i2c2_b_2, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(msp0txrx_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(i2c1_b_2, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(u2rxtx_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(uartmodtx_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(msp0sck_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(uartmodrx_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(stmmod_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(uartmodrx_b_2, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(kp_b_2, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(ipgpio7_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(ipgpio2_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(ipgpio3_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(lcdaclk_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(lcda_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(lcd_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(lcd_d16_d23_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(ddrtrig_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(pwl_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(spi1_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(mc3_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(pwl_b_2, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(pwl_b_3, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(pwl_b_4, NMK_GPIO_ALT_B), /* Altfunction C column */ - DB8500_PIN_GROUP(ipjtag_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio0_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio1_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio3_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio2_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(slim0_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ms_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(iptrigout_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(u2rxtx_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(u2ctsrts_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(u0_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio4_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio5_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio6_c_2, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio7_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(smcleale_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(stmape_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(u2rxtx_c_2, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio2_c_2, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio3_c_2, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio4_c_2, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(ipgpio5_c_2, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(mc5_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(mc2rstn_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(kp_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(smps0_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(smps1_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(u2rxtx_c_3, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(stmape_c_2, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(uartmodrx_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(uartmodtx_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(clkout1_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(clkout2_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipjtag_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio0_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio1_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio3_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio2_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(slim0_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ms_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(iptrigout_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(u2rxtx_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(u2ctsrts_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(u0_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio4_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio5_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio6_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio7_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(smcleale_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(stmape_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(u2rxtx_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio2_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio3_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio4_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(ipgpio5_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(mc5_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(mc2rstn_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(kp_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(smps0_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(smps1_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(u2rxtx_c_3, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(stmape_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(uartmodrx_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(uartmodtx_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(clkout1_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(clkout2_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C), /* Other alt C1 column */ - DB8500_PIN_GROUP(u2rx_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(ptma9_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(rf_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(hxclk_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(uartmodrx_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(uartmodtx_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(stmmod_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(hxgpio_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(rf_oc1_2, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1), - DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(u2rx_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(ptma9_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(rf_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(hxclk_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(uartmodrx_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(uartmodtx_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(stmmod_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(hxgpio_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(rf_oc1_2, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1), + NMK_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1), /* Other alt C2 column */ - DB8500_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2), - DB8500_PIN_GROUP(etmr4_oc2_1, NMK_GPIO_ALT_C2), - DB8500_PIN_GROUP(ptma9_oc2_1, NMK_GPIO_ALT_C2), + NMK_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2), + NMK_PIN_GROUP(etmr4_oc2_1, NMK_GPIO_ALT_C2), + NMK_PIN_GROUP(ptma9_oc2_1, NMK_GPIO_ALT_C2), /* Other alt C3 column */ - DB8500_PIN_GROUP(stmmod_oc3_1, NMK_GPIO_ALT_C3), - DB8500_PIN_GROUP(stmmod_oc3_2, NMK_GPIO_ALT_C3), - DB8500_PIN_GROUP(uartmodrx_oc3_1, NMK_GPIO_ALT_C3), - DB8500_PIN_GROUP(uartmodtx_oc3_1, NMK_GPIO_ALT_C3), - DB8500_PIN_GROUP(etmr4_oc3_1, NMK_GPIO_ALT_C3), + NMK_PIN_GROUP(stmmod_oc3_1, NMK_GPIO_ALT_C3), + NMK_PIN_GROUP(stmmod_oc3_2, NMK_GPIO_ALT_C3), + NMK_PIN_GROUP(uartmodrx_oc3_1, NMK_GPIO_ALT_C3), + NMK_PIN_GROUP(uartmodtx_oc3_1, NMK_GPIO_ALT_C3), + NMK_PIN_GROUP(etmr4_oc3_1, NMK_GPIO_ALT_C3), /* Other alt C4 column */ - DB8500_PIN_GROUP(sbag_oc4_1, NMK_GPIO_ALT_C4), - DB8500_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4), + NMK_PIN_GROUP(sbag_oc4_1, NMK_GPIO_ALT_C4), + NMK_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4), }; /* We use this macro to define the groups applicable to a function */ diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c index 8d944bb3a036..c0d7c86d0939 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c @@ -303,23 +303,20 @@ static const unsigned usbhs_c_1_pins[] = { STN8815_PIN_E21, STN8815_PIN_E20, STN8815_PIN_C16, STN8815_PIN_A15, STN8815_PIN_D17, STN8815_PIN_C17 }; -#define STN8815_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins, \ - .npins = ARRAY_SIZE(a##_pins), .altsetting = b } - static const struct nmk_pingroup nmk_stn8815_groups[] = { - STN8815_PIN_GROUP(u0txrx_a_1, NMK_GPIO_ALT_A), - STN8815_PIN_GROUP(u0ctsrts_a_1, NMK_GPIO_ALT_A), - STN8815_PIN_GROUP(u0modem_a_1, NMK_GPIO_ALT_A), - STN8815_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A), - STN8815_PIN_GROUP(mmcsd_b_1, NMK_GPIO_ALT_B), - STN8815_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A), - STN8815_PIN_GROUP(i2c1_a_1, NMK_GPIO_ALT_A), - STN8815_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), - STN8815_PIN_GROUP(u1_b_1, NMK_GPIO_ALT_B), - STN8815_PIN_GROUP(i2cusb_b_1, NMK_GPIO_ALT_B), - STN8815_PIN_GROUP(clcd_16_23_b_1, NMK_GPIO_ALT_B), - STN8815_PIN_GROUP(usbfs_b_1, NMK_GPIO_ALT_B), - STN8815_PIN_GROUP(usbhs_c_1, NMK_GPIO_ALT_C), + NMK_PIN_GROUP(u0txrx_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(u0ctsrts_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(u0modem_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(mmcsd_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(i2c1_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), + NMK_PIN_GROUP(u1_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(i2cusb_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(clcd_16_23_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(usbfs_b_1, NMK_GPIO_ALT_B), + NMK_PIN_GROUP(usbhs_c_1, NMK_GPIO_ALT_C), }; /* We use this macro to define the groups applicable to a function */ diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index f5014d09d81a..58c7ac8c7d4d 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -1179,17 +1179,17 @@ static const char *nmk_get_group_name(struct pinctrl_dev *pctldev, { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); - return npct->soc->groups[selector].name; + return npct->soc->groups[selector].grp.name; } static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, const unsigned **pins, - unsigned *num_pins) + unsigned *npins) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); - *pins = npct->soc->groups[selector].pins; - *num_pins = npct->soc->groups[selector].npins; + *pins = npct->soc->groups[selector].grp.pins; + *npins = npct->soc->groups[selector].grp.npins; return 0; } @@ -1531,7 +1531,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, if (g->altsetting < 0) return -EINVAL; - dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins); + dev_dbg(npct->dev, "enable group %s, %u pins\n", g->grp.name, g->grp.npins); /* * If we're setting altfunc C by setting both AFSLA and AFSLB to 1, @@ -1566,26 +1566,26 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, * Then mask the pins that need to be sleeping now when we're * switching to the ALT C function. */ - for (i = 0; i < g->npins; i++) - slpm[g->pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->pins[i]); + for (i = 0; i < g->grp.npins; i++) + slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->grp.pins[i]); nmk_gpio_glitch_slpm_init(slpm); } - for (i = 0; i < g->npins; i++) { + for (i = 0; i < g->grp.npins; i++) { struct nmk_gpio_chip *nmk_chip; unsigned bit; - nmk_chip = find_nmk_gpio_from_pin(g->pins[i]); + nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i]); if (!nmk_chip) { dev_err(npct->dev, "invalid pin offset %d in group %s at index %d\n", - g->pins[i], g->name, i); + g->grp.pins[i], g->grp.name, i); goto out_glitch; } - dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->pins[i], g->altsetting); + dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->grp.pins[i], g->altsetting); clk_enable(nmk_chip->clk); - bit = g->pins[i] % NMK_GPIO_PER_CHIP; + bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP; /* * If the pin is switching to altfunc, and there was an * interrupt installed on it which has been lazy disabled, @@ -1608,7 +1608,7 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function, * then some bits in PRCM GPIOCR registers must be cleared. */ if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C) - nmk_prcm_altcx_set_mode(npct, g->pins[i], + nmk_prcm_altcx_set_mode(npct, g->grp.pins[i], g->altsetting >> NMK_GPIO_ALT_CX_SHIFT); } diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h index ae0bac06639f..820f07f4db32 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.h +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.h @@ -105,21 +105,21 @@ struct nmk_function { /** * struct nmk_pingroup - describes a Nomadik pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @num_pins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array + * @grp: Generic data of the pin group (name and pins) * @altsetting: the altsetting to apply to all pins in this group to * configure them to be used by a function */ struct nmk_pingroup { - const char *name; - const unsigned int *pins; - const unsigned npins; + struct pingroup grp; int altsetting; }; +#define NMK_PIN_GROUP(a, b) \ + { \ + .grp = PINCTRL_PINGROUP(#a, a##_pins, ARRAY_SIZE(a##_pins)), \ + .altsetting = b, \ + } + /** * struct nmk_pinctrl_soc_data - Nomadik pin controller per-SoC configuration * @pins: An array describing all pins the pin controller affects. From 4faa4e73011d65583b25a5597c5f0e118e128ed3 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 17 Aug 2022 12:38:32 +0100 Subject: [PATCH 056/401] dt-bindings: pinctrl: qcom: Add sm8450 lpass lpi pinctrl bindings Add device tree binding Documentation details for Qualcomm SM8450 LPASS(Low Power Audio Sub System) LPI(Low Power Island) pinctrl driver. Signed-off-by: Srinivas Kandagatla Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20220817113833.9625-2-srinivas.kandagatla@linaro.org Signed-off-by: Linus Walleij --- .../qcom,sm8450-lpass-lpi-pinctrl.yaml | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml new file mode 100644 index 000000000000..3694795ec793 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml @@ -0,0 +1,135 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. Low Power Audio SubSystem (LPASS) + Low Power Island (LPI) TLMM block + +maintainers: + - Srinivas Kandagatla + +description: | + This binding describes the Top Level Mode Multiplexer block found in the + LPASS LPI IP on most Qualcomm SoCs + +properties: + compatible: + const: qcom,sm8450-lpass-lpi-pinctrl + + reg: + items: + - description: LPASS LPI TLMM Control and Status registers + - description: LPASS LPI pins SLEW registers + + clocks: + items: + - description: LPASS Core voting clock + - description: LPASS Audio voting clock + + clock-names: + items: + - const: core + - const: audio + + gpio-controller: true + + '#gpio-cells': + description: Specifying the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + gpio-ranges: + maxItems: 1 + +#PIN CONFIGURATION NODES +patternProperties: + '-pins$': + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: /schemas/pinctrl/pincfg-node.yaml + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + pattern: "^gpio([0-9]|[1-2][0-9]])$" + + function: + enum: [ swr_tx_clk, swr_tx_data, swr_rx_clk, swr_rx_data, + dmic1_clk, dmic1_data, dmic2_clk, dmic2_data, dmic4_clk, + dmic4_data, i2s2_clk, i2s2_ws, dmic3_clk, dmic3_data, + qua_mi2s_sclk, qua_mi2s_ws, qua_mi2s_data, i2s1_clk, i2s1_ws, + i2s1_data, wsa_swr_clk, wsa_swr_data, wsa2_swr_clk, + wsa2_swr_data, i2s2_data, i2s4_ws, i2s4_clk, i2s4_data, + slimbus_clk, i2s3_clk, i2s3_ws, i2s3_data, slimbus_data, + ext_mclk1_c, ext_mclk1_b, ext_mclk1_a, ext_mclk1_d, + ext_mclk1_e ] + description: + Specify the alternative function to be configured for the specified + pins. + + drive-strength: + enum: [2, 4, 6, 8, 10, 12, 14, 16] + default: 2 + description: + Selects the drive strength for the specified pins, in mA. + + slew-rate: + enum: [0, 1, 2, 3] + default: 0 + description: | + 0: No adjustments + 1: Higher Slew rate (faster edges) + 2: Lower Slew rate (slower edges) + 3: Reserved (No adjustments) + + bias-pull-down: true + + bias-pull-up: true + + bias-disable: true + + output-high: true + + output-low: true + + required: + - pins + - function + + additionalProperties: false + +allOf: + - $ref: pinctrl.yaml# + +required: + - compatible + - reg + - clocks + - clock-names + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + - | + #include + pinctrl@3440000 { + compatible = "qcom,sm8450-lpass-lpi-pinctrl"; + reg = <0x3440000 0x20000>, + <0x34d0000 0x10000>; + clocks = <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "core", "audio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&lpi_tlmm 0 0 23>; + }; From ec1652fc4d56660c33850176d06b3f1a02796946 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 17 Aug 2022 12:38:33 +0100 Subject: [PATCH 057/401] pinctrl: qcom: Add sm8450 lpass lpi pinctrl driver Add pinctrl driver to support pin configuration for LPASS (Low Power Audio SubSystem) LPI (Low Power Island) pinctrl on SM8450. This IP is an additional pin control block for Audio Pins on top the existing SoC Top level pin-controller. Hardware setup looks like: TLMM GPIO[165 - 187] --> LPASS LPI GPIO [0 - 22] This pin controller has some similarities compared to Top level msm SoC Pin controller like 'each pin belongs to a single group' and so on. However this one is intended to control only audio pins in particular, which can not be configured/touched by the Top level SoC pin controller except setting them as gpios. Apart from this, slew rate is also available in this block for certain pins which are connected to SLIMbus or SoundWire Bus. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220817113833.9625-3-srinivas.kandagatla@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Kconfig | 9 + drivers/pinctrl/qcom/Makefile | 1 + .../pinctrl/qcom/pinctrl-sm8450-lpass-lpi.c | 240 ++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-sm8450-lpass-lpi.c diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index f415c13caae0..35e59f940ddb 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -390,6 +390,15 @@ config PINCTRL_SM8450 Qualcomm Technologies Inc TLMM block found on the Qualcomm Technologies Inc SM8450 platform. +config PINCTRL_SM8450_LPASS_LPI + tristate "Qualcomm Technologies Inc SM8450 LPASS LPI pin controller driver" + depends on GPIOLIB + depends on PINCTRL_LPASS_LPI + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI + (Low Power Island) found on the Qualcomm Technologies Inc SM8450 platform. + config PINCTRL_LPASS_LPI tristate "Qualcomm Technologies Inc LPASS LPI pin controller driver" select PINMUX diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index fbd64853a24d..06e4cddbca68 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -45,4 +45,5 @@ obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o obj-$(CONFIG_PINCTRL_SM8250_LPASS_LPI) += pinctrl-sm8250-lpass-lpi.o obj-$(CONFIG_PINCTRL_SM8350) += pinctrl-sm8350.o obj-$(CONFIG_PINCTRL_SM8450) += pinctrl-sm8450.o +obj-$(CONFIG_PINCTRL_SM8450_LPASS_LPI) += pinctrl-sm8450-lpass-lpi.o obj-$(CONFIG_PINCTRL_LPASS_LPI) += pinctrl-lpass-lpi.o diff --git a/drivers/pinctrl/qcom/pinctrl-sm8450-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-sm8450-lpass-lpi.c new file mode 100644 index 000000000000..c3c8c34148f1 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-sm8450-lpass-lpi.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Linaro Ltd. + */ + +#include +#include +#include + +#include "pinctrl-lpass-lpi.h" + +enum lpass_lpi_functions { + LPI_MUX_dmic1_clk, + LPI_MUX_dmic1_data, + LPI_MUX_dmic2_clk, + LPI_MUX_dmic2_data, + LPI_MUX_dmic3_clk, + LPI_MUX_dmic3_data, + LPI_MUX_dmic4_clk, + LPI_MUX_dmic4_data, + LPI_MUX_i2s1_clk, + LPI_MUX_i2s1_data, + LPI_MUX_i2s1_ws, + LPI_MUX_i2s2_clk, + LPI_MUX_i2s2_data, + LPI_MUX_i2s2_ws, + LPI_MUX_i2s3_clk, + LPI_MUX_i2s3_data, + LPI_MUX_i2s3_ws, + LPI_MUX_i2s4_clk, + LPI_MUX_i2s4_data, + LPI_MUX_i2s4_ws, + LPI_MUX_qua_mi2s_data, + LPI_MUX_qua_mi2s_sclk, + LPI_MUX_qua_mi2s_ws, + LPI_MUX_swr_rx_clk, + LPI_MUX_swr_rx_data, + LPI_MUX_swr_tx_clk, + LPI_MUX_swr_tx_data, + LPI_MUX_wsa_swr_clk, + LPI_MUX_wsa_swr_data, + LPI_MUX_wsa2_swr_clk, + LPI_MUX_wsa2_swr_data, + LPI_MUX_slimbus_clk, + LPI_MUX_slimbus_data, + LPI_MUX_ext_mclk1_a, + LPI_MUX_ext_mclk1_b, + LPI_MUX_ext_mclk1_c, + LPI_MUX_ext_mclk1_d, + LPI_MUX_ext_mclk1_e, + LPI_MUX_gpio, + LPI_MUX__, +}; + +static int gpio0_pins[] = { 0 }; +static int gpio1_pins[] = { 1 }; +static int gpio2_pins[] = { 2 }; +static int gpio3_pins[] = { 3 }; +static int gpio4_pins[] = { 4 }; +static int gpio5_pins[] = { 5 }; +static int gpio6_pins[] = { 6 }; +static int gpio7_pins[] = { 7 }; +static int gpio8_pins[] = { 8 }; +static int gpio9_pins[] = { 9 }; +static int gpio10_pins[] = { 10 }; +static int gpio11_pins[] = { 11 }; +static int gpio12_pins[] = { 12 }; +static int gpio13_pins[] = { 13 }; +static int gpio14_pins[] = { 14 }; +static int gpio15_pins[] = { 15 }; +static int gpio16_pins[] = { 16 }; +static int gpio17_pins[] = { 17 }; +static int gpio18_pins[] = { 18 }; +static int gpio19_pins[] = { 19 }; +static int gpio20_pins[] = { 20 }; +static int gpio21_pins[] = { 21 }; +static int gpio22_pins[] = { 22 }; + +static const struct pinctrl_pin_desc sm8450_lpi_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), +}; + +static const char * const swr_tx_clk_groups[] = { "gpio0" }; +static const char * const swr_tx_data_groups[] = { "gpio1", "gpio2", "gpio14" }; +static const char * const swr_rx_clk_groups[] = { "gpio3" }; +static const char * const swr_rx_data_groups[] = { "gpio4", "gpio5", "gpio15" }; +static const char * const dmic1_clk_groups[] = { "gpio6" }; +static const char * const dmic1_data_groups[] = { "gpio7" }; +static const char * const dmic2_clk_groups[] = { "gpio8" }; +static const char * const dmic2_data_groups[] = { "gpio9" }; +static const char * const dmic4_clk_groups[] = { "gpio17" }; +static const char * const dmic4_data_groups[] = { "gpio18" }; +static const char * const i2s2_clk_groups[] = { "gpio10" }; +static const char * const i2s2_ws_groups[] = { "gpio11" }; +static const char * const dmic3_clk_groups[] = { "gpio12" }; +static const char * const dmic3_data_groups[] = { "gpio13" }; +static const char * const qua_mi2s_sclk_groups[] = { "gpio0" }; +static const char * const qua_mi2s_ws_groups[] = { "gpio1" }; +static const char * const qua_mi2s_data_groups[] = { "gpio2", "gpio3", "gpio4", "gpio5" }; +static const char * const i2s1_clk_groups[] = { "gpio6" }; +static const char * const i2s1_ws_groups[] = { "gpio7" }; +static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" }; +static const char * const wsa_swr_clk_groups[] = { "gpio10" }; +static const char * const wsa_swr_data_groups[] = { "gpio11" }; +static const char * const wsa2_swr_clk_groups[] = { "gpio15" }; +static const char * const wsa2_swr_data_groups[] = { "gpio16" }; +static const char * const i2s2_data_groups[] = { "gpio15", "gpio16" }; +static const char * const i2s4_ws_groups[] = { "gpio13" }; +static const char * const i2s4_clk_groups[] = { "gpio12" }; +static const char * const i2s4_data_groups[] = { "gpio17", "gpio18" }; +static const char * const slimbus_clk_groups[] = { "gpio19"}; +static const char * const i2s3_clk_groups[] = { "gpio19"}; +static const char * const i2s3_ws_groups[] = { "gpio20"}; +static const char * const i2s3_data_groups[] = { "gpio21", "gpio22"}; +static const char * const slimbus_data_groups[] = { "gpio20"}; +static const char * const ext_mclk1_c_groups[] = { "gpio5" }; +static const char * const ext_mclk1_b_groups[] = { "gpio9" }; +static const char * const ext_mclk1_a_groups[] = { "gpio13" }; +static const char * const ext_mclk1_d_groups[] = { "gpio14" }; +static const char * const ext_mclk1_e_groups[] = { "gpio22" }; + +static const struct lpi_pingroup sm8450_groups[] = { + LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _), + LPI_PINGROUP(1, 2, swr_tx_data, qua_mi2s_ws, _, _), + LPI_PINGROUP(2, 4, swr_tx_data, qua_mi2s_data, _, _), + LPI_PINGROUP(3, 8, swr_rx_clk, qua_mi2s_data, _, _), + LPI_PINGROUP(4, 10, swr_rx_data, qua_mi2s_data, _, _), + LPI_PINGROUP(5, 12, swr_rx_data, ext_mclk1_c, qua_mi2s_data, _), + LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, i2s1_clk, _, _), + LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, i2s1_ws, _, _), + LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, i2s1_data, _, _), + LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, i2s1_data, ext_mclk1_b, _), + LPI_PINGROUP(10, 16, i2s2_clk, wsa_swr_clk, _, _), + LPI_PINGROUP(11, 18, i2s2_ws, wsa_swr_data, _, _), + LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s4_clk, _, _), + LPI_PINGROUP(13, LPI_NO_SLEW, dmic3_data, i2s4_ws, ext_mclk1_a, _), + LPI_PINGROUP(14, 6, swr_tx_data, ext_mclk1_d, _, _), + LPI_PINGROUP(15, 20, i2s2_data, wsa2_swr_clk, _, _), + LPI_PINGROUP(16, 22, i2s2_data, wsa2_swr_data, _, _), + LPI_PINGROUP(17, LPI_NO_SLEW, dmic4_clk, i2s4_data, _, _), + LPI_PINGROUP(18, LPI_NO_SLEW, dmic4_data, i2s4_data, _, _), + LPI_PINGROUP(19, LPI_NO_SLEW, i2s3_clk, slimbus_clk, _, _), + LPI_PINGROUP(20, LPI_NO_SLEW, i2s3_ws, slimbus_data, _, _), + LPI_PINGROUP(21, LPI_NO_SLEW, i2s3_data, _, _, _), + LPI_PINGROUP(22, LPI_NO_SLEW, i2s3_data, ext_mclk1_e, _, _), +}; + +static const struct lpi_function sm8450_functions[] = { + LPI_FUNCTION(dmic1_clk), + LPI_FUNCTION(dmic1_data), + LPI_FUNCTION(dmic2_clk), + LPI_FUNCTION(dmic2_data), + LPI_FUNCTION(dmic3_clk), + LPI_FUNCTION(dmic3_data), + LPI_FUNCTION(dmic4_clk), + LPI_FUNCTION(dmic4_data), + LPI_FUNCTION(i2s1_clk), + LPI_FUNCTION(i2s1_data), + LPI_FUNCTION(i2s1_ws), + LPI_FUNCTION(i2s2_clk), + LPI_FUNCTION(i2s2_data), + LPI_FUNCTION(i2s2_ws), + LPI_FUNCTION(i2s3_clk), + LPI_FUNCTION(i2s3_data), + LPI_FUNCTION(i2s3_ws), + LPI_FUNCTION(i2s4_clk), + LPI_FUNCTION(i2s4_data), + LPI_FUNCTION(i2s4_ws), + LPI_FUNCTION(qua_mi2s_data), + LPI_FUNCTION(qua_mi2s_sclk), + LPI_FUNCTION(qua_mi2s_ws), + LPI_FUNCTION(swr_rx_clk), + LPI_FUNCTION(swr_rx_data), + LPI_FUNCTION(swr_tx_clk), + LPI_FUNCTION(swr_tx_data), + LPI_FUNCTION(slimbus_clk), + LPI_FUNCTION(slimbus_data), + LPI_FUNCTION(wsa_swr_clk), + LPI_FUNCTION(wsa_swr_data), + LPI_FUNCTION(wsa2_swr_clk), + LPI_FUNCTION(wsa2_swr_data), + LPI_FUNCTION(ext_mclk1_a), + LPI_FUNCTION(ext_mclk1_b), + LPI_FUNCTION(ext_mclk1_c), + LPI_FUNCTION(ext_mclk1_d), + LPI_FUNCTION(ext_mclk1_e), +}; + +static const struct lpi_pinctrl_variant_data sm8450_lpi_data = { + .pins = sm8450_lpi_pins, + .npins = ARRAY_SIZE(sm8450_lpi_pins), + .groups = sm8450_groups, + .ngroups = ARRAY_SIZE(sm8450_groups), + .functions = sm8450_functions, + .nfunctions = ARRAY_SIZE(sm8450_functions), +}; + +static const struct of_device_id lpi_pinctrl_of_match[] = { + { + .compatible = "qcom,sm8450-lpass-lpi-pinctrl", + .data = &sm8450_lpi_data, + }, + { } +}; +MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match); + +static struct platform_driver lpi_pinctrl_driver = { + .driver = { + .name = "qcom-sm8450-lpass-lpi-pinctrl", + .of_match_table = lpi_pinctrl_of_match, + }, + .probe = lpi_pinctrl_probe, + .remove = lpi_pinctrl_remove, +}; + +module_platform_driver(lpi_pinctrl_driver); +MODULE_DESCRIPTION("QTI SM8450 LPI GPIO pin control driver"); +MODULE_LICENSE("GPL"); From 958bb025f5b3138217ffd4479b1877ba53297df9 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 17 Aug 2022 12:37:46 +0100 Subject: [PATCH 058/401] dt-bindings: pinctrl: qcom: Add sc8280xp lpass lpi pinctrl bindings Add device tree binding Documentation details for Qualcomm SC8280XP LPASS(Low Power Audio Sub System) LPI(Low Power Island) pinctrl driver. Signed-off-by: Srinivas Kandagatla Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20220817113747.9111-2-srinivas.kandagatla@linaro.org Signed-off-by: Linus Walleij --- .../qcom,sc8280xp-lpass-lpi-pinctrl.yaml | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-lpass-lpi-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-lpass-lpi-pinctrl.yaml new file mode 100644 index 000000000000..1f468303bb08 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-lpass-lpi-pinctrl.yaml @@ -0,0 +1,133 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,sc8280xp-lpass-lpi-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. Low Power Audio SubSystem (LPASS) + Low Power Island (LPI) TLMM block + +maintainers: + - Srinivas Kandagatla + +description: | + This binding describes the Top Level Mode Multiplexer block found in the + LPASS LPI IP on most Qualcomm SoCs + +properties: + compatible: + const: qcom,sc8280xp-lpass-lpi-pinctrl + + reg: + items: + - description: LPASS LPI TLMM Control and Status registers + - description: LPASS LPI pins SLEW registers + + clocks: + items: + - description: LPASS Core voting clock + - description: LPASS Audio voting clock + + clock-names: + items: + - const: core + - const: audio + + gpio-controller: true + + '#gpio-cells': + description: Specifying the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + gpio-ranges: + maxItems: 1 + +#PIN CONFIGURATION NODES +patternProperties: + '-pins$': + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: /schemas/pinctrl/pincfg-node.yaml + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + pattern: "^gpio([0-1]|1[0-8]])$" + + function: + enum: [ swr_tx_clk, swr_tx_data, swr_rx_clk, swr_rx_data, + dmic1_clk, dmic1_data, dmic2_clk, dmic2_data, dmic4_clk, + dmic4_data, i2s2_clk, i2s2_ws, dmic3_clk, dmic3_data, + qua_mi2s_sclk, qua_mi2s_ws, qua_mi2s_data, i2s1_clk, i2s1_ws, + i2s1_data, wsa_swr_clk, wsa_swr_data, wsa2_swr_clk, + wsa2_swr_data, i2s2_data, i2s3_clk, i2s3_ws, i2s3_data, + ext_mclk1_c, ext_mclk1_b, ext_mclk1_a ] + description: + Specify the alternative function to be configured for the specified + pins. + + drive-strength: + enum: [2, 4, 6, 8, 10, 12, 14, 16] + default: 2 + description: + Selects the drive strength for the specified pins, in mA. + + slew-rate: + enum: [0, 1, 2, 3] + default: 0 + description: | + 0: No adjustments + 1: Higher Slew rate (faster edges) + 2: Lower Slew rate (slower edges) + 3: Reserved (No adjustments) + + bias-pull-down: true + + bias-pull-up: true + + bias-disable: true + + output-high: true + + output-low: true + + required: + - pins + - function + + additionalProperties: false + +allOf: + - $ref: pinctrl.yaml# + +required: + - compatible + - reg + - clocks + - clock-names + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + - | + #include + pinctrl@33c0000 { + compatible = "qcom,sc8280xp-lpass-lpi-pinctrl"; + reg = <0x33c0000 0x20000>, + <0x3550000 0x10000>; + clocks = <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "core", "audio"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&lpi_tlmm 0 0 18>; + }; From 67f40373ee7b419374b191cedd63a05afd33a459 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 17 Aug 2022 12:37:47 +0100 Subject: [PATCH 059/401] pinctrl: qcom: Add sc8280xp lpass lpi pinctrl driver Add pinctrl driver to support pin configuration for LPASS (Low Power Audio SubSystem) LPI (Low Power Island) pinctrl on SC8280XP. This IP is an additional pin control block for Audio Pins on top the existing SoC Top level pin-controller. Hardware setup looks like: TLMM GPIO[189 - 207] --> LPASS LPI GPIO [0 - 18] This pin controller has some similarities compared to Top level msm SoC Pin controller like 'each pin belongs to a single group' and so on. However this one is intended to control only audio pins in particular, which can not be configured/touched by the Top level SoC pin controller except setting them as gpios. Apart from this, slew rate is also available in this block for certain pins which are connected to SLIMbus or SoundWire Bus. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220817113747.9111-3-srinivas.kandagatla@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Kconfig | 9 + drivers/pinctrl/qcom/Makefile | 1 + .../pinctrl/qcom/pinctrl-sc8280xp-lpass-lpi.c | 207 ++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-sc8280xp-lpass-lpi.c diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 35e59f940ddb..2961b5eb8e10 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -399,6 +399,15 @@ config PINCTRL_SM8450_LPASS_LPI Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI (Low Power Island) found on the Qualcomm Technologies Inc SM8450 platform. +config PINCTRL_SC8280XP_LPASS_LPI + tristate "Qualcomm Technologies Inc SC8280XP LPASS LPI pin controller driver" + depends on GPIOLIB + depends on PINCTRL_LPASS_LPI + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI + (Low Power Island) found on the Qualcomm Technologies Inc SC8280XP platform. + config PINCTRL_LPASS_LPI tristate "Qualcomm Technologies Inc LPASS LPI pin controller driver" select PINMUX diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 06e4cddbca68..8269a1db8794 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -46,4 +46,5 @@ obj-$(CONFIG_PINCTRL_SM8250_LPASS_LPI) += pinctrl-sm8250-lpass-lpi.o obj-$(CONFIG_PINCTRL_SM8350) += pinctrl-sm8350.o obj-$(CONFIG_PINCTRL_SM8450) += pinctrl-sm8450.o obj-$(CONFIG_PINCTRL_SM8450_LPASS_LPI) += pinctrl-sm8450-lpass-lpi.o +obj-$(CONFIG_PINCTRL_SC8280XP_LPASS_LPI) += pinctrl-sc8280xp-lpass-lpi.o obj-$(CONFIG_PINCTRL_LPASS_LPI) += pinctrl-lpass-lpi.o diff --git a/drivers/pinctrl/qcom/pinctrl-sc8280xp-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-sc8280xp-lpass-lpi.c new file mode 100644 index 000000000000..4b9c0beac32e --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-sc8280xp-lpass-lpi.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Linaro Ltd. + */ + +#include +#include +#include + +#include "pinctrl-lpass-lpi.h" + +enum lpass_lpi_functions { + LPI_MUX_dmic1_clk, + LPI_MUX_dmic1_data, + LPI_MUX_dmic2_clk, + LPI_MUX_dmic2_data, + LPI_MUX_dmic3_clk, + LPI_MUX_dmic3_data, + LPI_MUX_dmic4_clk, + LPI_MUX_dmic4_data, + LPI_MUX_i2s1_clk, + LPI_MUX_i2s1_data, + LPI_MUX_i2s1_ws, + LPI_MUX_i2s2_clk, + LPI_MUX_i2s2_data, + LPI_MUX_i2s2_ws, + LPI_MUX_i2s3_clk, + LPI_MUX_i2s3_data, + LPI_MUX_i2s3_ws, + LPI_MUX_qua_mi2s_data, + LPI_MUX_qua_mi2s_sclk, + LPI_MUX_qua_mi2s_ws, + LPI_MUX_swr_rx_clk, + LPI_MUX_swr_rx_data, + LPI_MUX_swr_tx_clk, + LPI_MUX_swr_tx_data, + LPI_MUX_wsa_swr_clk, + LPI_MUX_wsa_swr_data, + LPI_MUX_wsa2_swr_clk, + LPI_MUX_wsa2_swr_data, + LPI_MUX_ext_mclk1_a, + LPI_MUX_ext_mclk1_b, + LPI_MUX_ext_mclk1_c, + LPI_MUX_gpio, + LPI_MUX__, +}; + +static int gpio0_pins[] = { 0 }; +static int gpio1_pins[] = { 1 }; +static int gpio2_pins[] = { 2 }; +static int gpio3_pins[] = { 3 }; +static int gpio4_pins[] = { 4 }; +static int gpio5_pins[] = { 5 }; +static int gpio6_pins[] = { 6 }; +static int gpio7_pins[] = { 7 }; +static int gpio8_pins[] = { 8 }; +static int gpio9_pins[] = { 9 }; +static int gpio10_pins[] = { 10 }; +static int gpio11_pins[] = { 11 }; +static int gpio12_pins[] = { 12 }; +static int gpio13_pins[] = { 13 }; +static int gpio14_pins[] = { 14 }; +static int gpio15_pins[] = { 15 }; +static int gpio16_pins[] = { 16 }; +static int gpio17_pins[] = { 17 }; +static int gpio18_pins[] = { 18 }; + +static const struct pinctrl_pin_desc sc8280xp_lpi_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), +}; + +static const char * const swr_tx_clk_groups[] = { "gpio0" }; +static const char * const swr_tx_data_groups[] = { "gpio1", "gpio2", "gpio14" }; +static const char * const swr_rx_clk_groups[] = { "gpio3" }; +static const char * const swr_rx_data_groups[] = { "gpio4", "gpio5" }; +static const char * const dmic1_clk_groups[] = { "gpio6" }; +static const char * const dmic1_data_groups[] = { "gpio7" }; +static const char * const dmic2_clk_groups[] = { "gpio8" }; +static const char * const dmic2_data_groups[] = { "gpio9" }; +static const char * const dmic4_clk_groups[] = { "gpio17" }; +static const char * const dmic4_data_groups[] = { "gpio18" }; +static const char * const i2s2_clk_groups[] = { "gpio10" }; +static const char * const i2s2_ws_groups[] = { "gpio11" }; +static const char * const dmic3_clk_groups[] = { "gpio12" }; +static const char * const dmic3_data_groups[] = { "gpio13" }; +static const char * const qua_mi2s_sclk_groups[] = { "gpio0" }; +static const char * const qua_mi2s_ws_groups[] = { "gpio1" }; +static const char * const qua_mi2s_data_groups[] = { "gpio2", "gpio3", "gpio4", "gpio5" }; +static const char * const i2s1_clk_groups[] = { "gpio6" }; +static const char * const i2s1_ws_groups[] = { "gpio7" }; +static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" }; +static const char * const wsa_swr_clk_groups[] = { "gpio10" }; +static const char * const wsa_swr_data_groups[] = { "gpio11" }; +static const char * const wsa2_swr_clk_groups[] = { "gpio15" }; +static const char * const wsa2_swr_data_groups[] = { "gpio16" }; +static const char * const i2s2_data_groups[] = { "gpio15", "gpio16" }; +static const char * const i2s3_clk_groups[] = { "gpio12"}; +static const char * const i2s3_ws_groups[] = { "gpio13"}; +static const char * const i2s3_data_groups[] = { "gpio17", "gpio18"}; +static const char * const ext_mclk1_c_groups[] = { "gpio5" }; +static const char * const ext_mclk1_b_groups[] = { "gpio9" }; +static const char * const ext_mclk1_a_groups[] = { "gpio13" }; + +static const struct lpi_pingroup sc8280xp_groups[] = { + LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _), + LPI_PINGROUP(1, 2, swr_tx_data, qua_mi2s_ws, _, _), + LPI_PINGROUP(2, 4, swr_tx_data, qua_mi2s_data, _, _), + LPI_PINGROUP(3, 8, swr_rx_clk, qua_mi2s_data, _, _), + LPI_PINGROUP(4, 10, swr_rx_data, qua_mi2s_data, _, _), + LPI_PINGROUP(5, 12, swr_rx_data, ext_mclk1_c, qua_mi2s_data, _), + LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, i2s1_clk, _, _), + LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, i2s1_ws, _, _), + LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, i2s1_data, _, _), + LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, i2s1_data, ext_mclk1_b, _), + LPI_PINGROUP(10, 16, i2s2_clk, wsa_swr_clk, _, _), + LPI_PINGROUP(11, 18, i2s2_ws, wsa_swr_data, _, _), + LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s3_clk, _, _), + LPI_PINGROUP(13, LPI_NO_SLEW, dmic3_data, i2s3_ws, ext_mclk1_a, _), + LPI_PINGROUP(14, 6, swr_tx_data, _, _, _), + LPI_PINGROUP(15, 20, i2s2_data, wsa2_swr_clk, _, _), + LPI_PINGROUP(16, 22, i2s2_data, wsa2_swr_data, _, _), + LPI_PINGROUP(17, LPI_NO_SLEW, dmic4_clk, i2s3_data, _, _), + LPI_PINGROUP(18, LPI_NO_SLEW, dmic4_data, i2s3_data, _, _), +}; + +static const struct lpi_function sc8280xp_functions[] = { + LPI_FUNCTION(dmic1_clk), + LPI_FUNCTION(dmic1_data), + LPI_FUNCTION(dmic2_clk), + LPI_FUNCTION(dmic2_data), + LPI_FUNCTION(dmic3_clk), + LPI_FUNCTION(dmic3_data), + LPI_FUNCTION(dmic4_clk), + LPI_FUNCTION(dmic4_data), + LPI_FUNCTION(i2s1_clk), + LPI_FUNCTION(i2s1_data), + LPI_FUNCTION(i2s1_ws), + LPI_FUNCTION(i2s2_clk), + LPI_FUNCTION(i2s2_data), + LPI_FUNCTION(i2s2_ws), + LPI_FUNCTION(i2s3_clk), + LPI_FUNCTION(i2s3_data), + LPI_FUNCTION(i2s3_ws), + LPI_FUNCTION(qua_mi2s_data), + LPI_FUNCTION(qua_mi2s_sclk), + LPI_FUNCTION(qua_mi2s_ws), + LPI_FUNCTION(swr_rx_clk), + LPI_FUNCTION(swr_rx_data), + LPI_FUNCTION(swr_tx_clk), + LPI_FUNCTION(swr_tx_data), + LPI_FUNCTION(wsa_swr_clk), + LPI_FUNCTION(wsa_swr_data), + LPI_FUNCTION(wsa2_swr_clk), + LPI_FUNCTION(wsa2_swr_data), + LPI_FUNCTION(ext_mclk1_a), + LPI_FUNCTION(ext_mclk1_b), + LPI_FUNCTION(ext_mclk1_c), +}; + +static const struct lpi_pinctrl_variant_data sc8280xp_lpi_data = { + .pins = sc8280xp_lpi_pins, + .npins = ARRAY_SIZE(sc8280xp_lpi_pins), + .groups = sc8280xp_groups, + .ngroups = ARRAY_SIZE(sc8280xp_groups), + .functions = sc8280xp_functions, + .nfunctions = ARRAY_SIZE(sc8280xp_functions), +}; + +static const struct of_device_id lpi_pinctrl_of_match[] = { + { + .compatible = "qcom,sc8280xp-lpass-lpi-pinctrl", + .data = &sc8280xp_lpi_data, + }, + { } +}; +MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match); + +static struct platform_driver lpi_pinctrl_driver = { + .driver = { + .name = "qcom-sc8280xp-lpass-lpi-pinctrl", + .of_match_table = lpi_pinctrl_of_match, + }, + .probe = lpi_pinctrl_probe, + .remove = lpi_pinctrl_remove, +}; + +module_platform_driver(lpi_pinctrl_driver); +MODULE_DESCRIPTION("QTI SC8280XP LPI GPIO pin control driver"); +MODULE_LICENSE("GPL"); From 9f1bdd7e822147a481cd75c0b2ac4d0199ac70d3 Mon Sep 17 00:00:00 2001 From: "Hui.Liu" Date: Thu, 18 Aug 2022 15:50:11 +0800 Subject: [PATCH 060/401] dt-bindings: pinctrl: mediatek: add support for mt8188 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the pinctrl header file on MediaTek mt8188. Add the new binding document for pinctrl on MediaTek mt8188. Signed-off-by: Hui.Liu Reviewed-by: Rob Herring Reviewed-by: Nícolas F. R. A. Prado Link: https://lore.kernel.org/r/20220818075012.20880-2-hui.liu@mediatek.com Signed-off-by: Linus Walleij --- .../pinctrl/mediatek,mt8188-pinctrl.yaml | 226 +++ .../pinctrl/mediatek,mt8188-pinfunc.h | 1280 +++++++++++++++++ 2 files changed, 1506 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt8188-pinctrl.yaml create mode 100644 include/dt-bindings/pinctrl/mediatek,mt8188-pinfunc.h diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt8188-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt8188-pinctrl.yaml new file mode 100644 index 000000000000..7e750f1e643d --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt8188-pinctrl.yaml @@ -0,0 +1,226 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt8188-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT8188 Pin Controller + +maintainers: + - Hui Liu + +description: | + The MediaTek's MT8188 Pin controller is used to control SoC pins. + +properties: + compatible: + const: mediatek,mt8188-pinctrl + + gpio-controller: true + + '#gpio-cells': + description: | + Number of cells in GPIO specifier, should be two. The first cell + is the pin number, the second cell is used to specify optional + parameters which are defined in . + const: 2 + + gpio-ranges: + maxItems: 1 + + gpio-line-names: true + + reg: + items: + - description: gpio registers base address + - description: rm group io configuration registers base address + - description: lt group io configuration registers base address + - description: lm group io configuration registers base address + - description: rt group io configuration registers base address + - description: eint registers base address + + reg-names: + items: + - const: iocfg0 + - const: iocfg_rm + - const: iocfg_lt + - const: iocfg_lm + - const: iocfg_rt + - const: eint + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + + interrupts: + description: The interrupt outputs to sysirq. + maxItems: 1 + + mediatek,rsel-resistance-in-si-unit: + type: boolean + description: | + We provide two methods to select the resistance for I2C when pull up or pull down. + The first is by RSEL definition value, another one is by resistance value(ohm). + This flag is used to identify if the method is resistance(si unit) value. + +# PIN CONFIGURATION NODES +patternProperties: + '-pins$': + type: object + additionalProperties: false + + patternProperties: + '^pins': + type: object + $ref: "/schemas/pinctrl/pincfg-node.yaml" + additionalProperties: false + description: | + A pinctrl node should contain at least one subnode representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to muxer + configuration, pullups, drive strength, input enable/disable and + input schmitt. + + properties: + pinmux: + description: | + Integer array, represents gpio pin number and mux setting. + Supported pin number and mux varies for different SoCs, and are + defined as macros in dt-bindings/pinctrl/mediatek,-pinfunc.h + directly. + + drive-strength: + enum: [2, 4, 6, 8, 10, 12, 14, 16] + + drive-strength-microamp: + enum: [125, 250, 500, 1000] + + bias-pull-down: + oneOf: + - type: boolean + - enum: [100, 101, 102, 103] + description: mt8188 pull down PUPD/R0/R1 type define value. + - enum: [200, 201, 202, 203, 204, 205, 206, 207] + description: mt8188 pull down RSEL type define value. + - enum: [75000, 5000] + description: mt8188 pull down RSEL type si unit value(ohm). + description: | + For pull down type is normal, it doesn't need add RSEL & R1R0 define + and resistance value. + For pull down type is PUPD/R0/R1 type, it can add R1R0 define to + set different resistance. It can support "MTK_PUPD_SET_R1R0_00" & + "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11" + define in mt8188. + For pull down type is RSEL, it can add RSEL define & resistance value(ohm) + to set different resistance by identifying property "mediatek,rsel-resistance-in-si-unit". + It can support "MTK_PULL_SET_RSEL_000" & "MTK_PULL_SET_RSEL_001" + & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" & "MTK_PULL_SET_RSEL_100" + & "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" & "MTK_PULL_SET_RSEL_111" + define in mt8188. It can also support resistance value(ohm) "75000" & "5000" in mt8188. + + bias-pull-up: + oneOf: + - type: boolean + - enum: [100, 101, 102, 103] + description: mt8188 pull up PUPD/R0/R1 type define value. + - enum: [200, 201, 202, 203, 204, 205, 206, 207] + description: mt8188 pull up RSEL type define value. + - enum: [1000, 1500, 2000, 3000, 4000, 5000, 10000, 75000] + description: mt8188 pull up RSEL type si unit value(ohm). + description: | + For pull up type is normal, it don't need add RSEL & R1R0 define + and resistance value. + For pull up type is PUPD/R0/R1 type, it can add R1R0 define to + set different resistance. It can support "MTK_PUPD_SET_R1R0_00" & + "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11" + define in mt8188. + For pull up type is RSEL, it can add RSEL define & resistance value(ohm) + to set different resistance by identifying property "mediatek,rsel-resistance-in-si-unit". + It can support "MTK_PULL_SET_RSEL_000" & "MTK_PULL_SET_RSEL_001" + & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" & "MTK_PULL_SET_RSEL_100" + & "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" & "MTK_PULL_SET_RSEL_111" + define in mt8188. It can also support resistance value(ohm) + "1000" & "1500" & "2000" & "3000" & "4000" & "5000" & "10000" & "75000" in mt8188. + + bias-disable: true + + output-high: true + + output-low: true + + input-enable: true + + input-disable: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + required: + - pinmux + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - '#interrupt-cells' + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + - | + #include + #include + + pio: pinctrl@10005000 { + compatible = "mediatek,mt8188-pinctrl"; + reg = <0x10005000 0x1000>, + <0x11c00000 0x1000>, + <0x11e10000 0x1000>, + <0x11e20000 0x1000>, + <0x11ea0000 0x1000>, + <0x1000b000 0x1000>; + reg-names = "iocfg0", "iocfg_rm", + "iocfg_lt", "iocfg_lm", "iocfg_rt", + "eint"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 176>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <2>; + + pio-pins { + pins { + pinmux = ; + output-low; + }; + }; + + spi0-pins { + pins-spi { + pinmux = , + , + ; + drive-strength = <6>; + }; + pins-spi-mi { + pinmux = ; + bias-pull-down = ; + }; + }; + + i2c0-pins { + pins { + pinmux = , + ; + bias-disable; + drive-strength-microamp = <1000>; + }; + }; + }; diff --git a/include/dt-bindings/pinctrl/mediatek,mt8188-pinfunc.h b/include/dt-bindings/pinctrl/mediatek,mt8188-pinfunc.h new file mode 100644 index 000000000000..2688da2f621f --- /dev/null +++ b/include/dt-bindings/pinctrl/mediatek,mt8188-pinfunc.h @@ -0,0 +1,1280 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Hui Liu + */ + +#ifndef __MEDIATEK_MT8188_PINFUNC_H +#define __MEDIATEK_MT8188_PINFUNC_H + +#include "mt65xx.h" + +#define PINMUX_GPIO0__FUNC_B_GPIO0 (MTK_PIN_NO(0) | 0) +#define PINMUX_GPIO0__FUNC_B0_TP_GPIO0_AO (MTK_PIN_NO(0) | 1) +#define PINMUX_GPIO0__FUNC_O_SPIM5_CSB (MTK_PIN_NO(0) | 2) +#define PINMUX_GPIO0__FUNC_O_UTXD1 (MTK_PIN_NO(0) | 3) +#define PINMUX_GPIO0__FUNC_O_DMIC3_CLK (MTK_PIN_NO(0) | 4) +#define PINMUX_GPIO0__FUNC_B0_I2SIN_MCK (MTK_PIN_NO(0) | 5) +#define PINMUX_GPIO0__FUNC_O_I2SO2_MCK (MTK_PIN_NO(0) | 6) +#define PINMUX_GPIO0__FUNC_B0_DBG_MON_A0 (MTK_PIN_NO(0) | 7) + +#define PINMUX_GPIO1__FUNC_B_GPIO1 (MTK_PIN_NO(1) | 0) +#define PINMUX_GPIO1__FUNC_B0_TP_GPIO1_AO (MTK_PIN_NO(1) | 1) +#define PINMUX_GPIO1__FUNC_O_SPIM5_CLK (MTK_PIN_NO(1) | 2) +#define PINMUX_GPIO1__FUNC_I1_URXD1 (MTK_PIN_NO(1) | 3) +#define PINMUX_GPIO1__FUNC_I0_DMIC3_DAT (MTK_PIN_NO(1) | 4) +#define PINMUX_GPIO1__FUNC_B0_I2SIN_BCK (MTK_PIN_NO(1) | 5) +#define PINMUX_GPIO1__FUNC_B0_I2SO2_BCK (MTK_PIN_NO(1) | 6) +#define PINMUX_GPIO1__FUNC_B0_DBG_MON_A1 (MTK_PIN_NO(1) | 7) + +#define PINMUX_GPIO2__FUNC_B_GPIO2 (MTK_PIN_NO(2) | 0) +#define PINMUX_GPIO2__FUNC_B0_TP_GPIO2_AO (MTK_PIN_NO(2) | 1) +#define PINMUX_GPIO2__FUNC_B0_SPIM5_MOSI (MTK_PIN_NO(2) | 2) +#define PINMUX_GPIO2__FUNC_O_URTS1 (MTK_PIN_NO(2) | 3) +#define PINMUX_GPIO2__FUNC_I0_DMIC3_DAT_R (MTK_PIN_NO(2) | 4) +#define PINMUX_GPIO2__FUNC_B0_I2SIN_WS (MTK_PIN_NO(2) | 5) +#define PINMUX_GPIO2__FUNC_B0_I2SO2_WS (MTK_PIN_NO(2) | 6) +#define PINMUX_GPIO2__FUNC_B0_DBG_MON_A2 (MTK_PIN_NO(2) | 7) + +#define PINMUX_GPIO3__FUNC_B_GPIO3 (MTK_PIN_NO(3) | 0) +#define PINMUX_GPIO3__FUNC_B0_TP_GPIO3_AO (MTK_PIN_NO(3) | 1) +#define PINMUX_GPIO3__FUNC_B0_SPIM5_MISO (MTK_PIN_NO(3) | 2) +#define PINMUX_GPIO3__FUNC_I1_UCTS1 (MTK_PIN_NO(3) | 3) +#define PINMUX_GPIO3__FUNC_O_DMIC4_CLK (MTK_PIN_NO(3) | 4) +#define PINMUX_GPIO3__FUNC_I0_I2SIN_D0 (MTK_PIN_NO(3) | 5) +#define PINMUX_GPIO3__FUNC_O_I2SO2_D0 (MTK_PIN_NO(3) | 6) +#define PINMUX_GPIO3__FUNC_B0_DBG_MON_A3 (MTK_PIN_NO(3) | 7) + +#define PINMUX_GPIO4__FUNC_B_GPIO4 (MTK_PIN_NO(4) | 0) +#define PINMUX_GPIO4__FUNC_B0_TP_GPIO4_AO (MTK_PIN_NO(4) | 1) +#define PINMUX_GPIO4__FUNC_I0_SPDIF_IN2 (MTK_PIN_NO(4) | 2) +#define PINMUX_GPIO4__FUNC_O_I2SO1_MCK (MTK_PIN_NO(4) | 3) +#define PINMUX_GPIO4__FUNC_I0_DMIC4_DAT (MTK_PIN_NO(4) | 4) +#define PINMUX_GPIO4__FUNC_I0_I2SIN_D1 (MTK_PIN_NO(4) | 5) +#define PINMUX_GPIO4__FUNC_O_I2SO2_D1 (MTK_PIN_NO(4) | 6) +#define PINMUX_GPIO4__FUNC_B0_DBG_MON_A4 (MTK_PIN_NO(4) | 7) + +#define PINMUX_GPIO5__FUNC_B_GPIO5 (MTK_PIN_NO(5) | 0) +#define PINMUX_GPIO5__FUNC_B0_TP_GPIO5_AO (MTK_PIN_NO(5) | 1) +#define PINMUX_GPIO5__FUNC_I0_SPDIF_IN1 (MTK_PIN_NO(5) | 2) +#define PINMUX_GPIO5__FUNC_O_I2SO1_BCK (MTK_PIN_NO(5) | 3) +#define PINMUX_GPIO5__FUNC_I0_DMIC4_DAT_R (MTK_PIN_NO(5) | 4) +#define PINMUX_GPIO5__FUNC_I0_I2SIN_D2 (MTK_PIN_NO(5) | 5) +#define PINMUX_GPIO5__FUNC_O_I2SO2_D2 (MTK_PIN_NO(5) | 6) +#define PINMUX_GPIO5__FUNC_B0_DBG_MON_A5 (MTK_PIN_NO(5) | 7) + +#define PINMUX_GPIO6__FUNC_B_GPIO6 (MTK_PIN_NO(6) | 0) +#define PINMUX_GPIO6__FUNC_B0_TP_GPIO6_AO (MTK_PIN_NO(6) | 1) +#define PINMUX_GPIO6__FUNC_I0_SPDIF_IN0 (MTK_PIN_NO(6) | 2) +#define PINMUX_GPIO6__FUNC_O_I2SO1_WS (MTK_PIN_NO(6) | 3) +#define PINMUX_GPIO6__FUNC_O_DMIC1_CLK (MTK_PIN_NO(6) | 4) +#define PINMUX_GPIO6__FUNC_I0_I2SIN_D3 (MTK_PIN_NO(6) | 5) +#define PINMUX_GPIO6__FUNC_O_I2SO2_D3 (MTK_PIN_NO(6) | 6) +#define PINMUX_GPIO6__FUNC_B0_MD32_0_GPIO0 (MTK_PIN_NO(6) | 7) + +#define PINMUX_GPIO7__FUNC_B_GPIO7 (MTK_PIN_NO(7) | 0) +#define PINMUX_GPIO7__FUNC_B0_TP_GPIO7_AO (MTK_PIN_NO(7) | 1) +#define PINMUX_GPIO7__FUNC_O_SPIM3_CSB (MTK_PIN_NO(7) | 2) +#define PINMUX_GPIO7__FUNC_B0_TDMIN_MCK (MTK_PIN_NO(7) | 3) +#define PINMUX_GPIO7__FUNC_I0_DMIC1_DAT (MTK_PIN_NO(7) | 4) +#define PINMUX_GPIO7__FUNC_O_CMVREF0 (MTK_PIN_NO(7) | 5) +#define PINMUX_GPIO7__FUNC_O_CLKM0 (MTK_PIN_NO(7) | 6) +#define PINMUX_GPIO7__FUNC_B0_DBG_MON_A6 (MTK_PIN_NO(7) | 7) + +#define PINMUX_GPIO8__FUNC_B_GPIO8 (MTK_PIN_NO(8) | 0) +#define PINMUX_GPIO8__FUNC_B0_TP_GPIO0_AO (MTK_PIN_NO(8) | 1) +#define PINMUX_GPIO8__FUNC_O_SPIM3_CLK (MTK_PIN_NO(8) | 2) +#define PINMUX_GPIO8__FUNC_B0_TDMIN_BCK (MTK_PIN_NO(8) | 3) +#define PINMUX_GPIO8__FUNC_I0_DMIC1_DAT_R (MTK_PIN_NO(8) | 4) +#define PINMUX_GPIO8__FUNC_O_CMVREF1 (MTK_PIN_NO(8) | 5) +#define PINMUX_GPIO8__FUNC_O_CLKM1 (MTK_PIN_NO(8) | 6) +#define PINMUX_GPIO8__FUNC_B0_DBG_MON_A7 (MTK_PIN_NO(8) | 7) + +#define PINMUX_GPIO9__FUNC_B_GPIO9 (MTK_PIN_NO(9) | 0) +#define PINMUX_GPIO9__FUNC_B0_TP_GPIO1_AO (MTK_PIN_NO(9) | 1) +#define PINMUX_GPIO9__FUNC_B0_SPIM3_MOSI (MTK_PIN_NO(9) | 2) +#define PINMUX_GPIO9__FUNC_B0_TDMIN_LRCK (MTK_PIN_NO(9) | 3) +#define PINMUX_GPIO9__FUNC_O_DMIC2_CLK (MTK_PIN_NO(9) | 4) +#define PINMUX_GPIO9__FUNC_O_CMFLASH0 (MTK_PIN_NO(9) | 5) +#define PINMUX_GPIO9__FUNC_O_PWM_0 (MTK_PIN_NO(9) | 6) +#define PINMUX_GPIO9__FUNC_B0_DBG_MON_A8 (MTK_PIN_NO(9) | 7) + +#define PINMUX_GPIO10__FUNC_B_GPIO10 (MTK_PIN_NO(10) | 0) +#define PINMUX_GPIO10__FUNC_B0_TP_GPIO2_AO (MTK_PIN_NO(10) | 1) +#define PINMUX_GPIO10__FUNC_B0_SPIM3_MISO (MTK_PIN_NO(10) | 2) +#define PINMUX_GPIO10__FUNC_I0_TDMIN_DI (MTK_PIN_NO(10) | 3) +#define PINMUX_GPIO10__FUNC_I0_DMIC2_DAT (MTK_PIN_NO(10) | 4) +#define PINMUX_GPIO10__FUNC_O_CMFLASH1 (MTK_PIN_NO(10) | 5) +#define PINMUX_GPIO10__FUNC_O_PWM_1 (MTK_PIN_NO(10) | 6) +#define PINMUX_GPIO10__FUNC_B0_DBG_MON_A9 (MTK_PIN_NO(10) | 7) + +#define PINMUX_GPIO11__FUNC_B_GPIO11 (MTK_PIN_NO(11) | 0) +#define PINMUX_GPIO11__FUNC_B0_TP_GPIO3_AO (MTK_PIN_NO(11) | 1) +#define PINMUX_GPIO11__FUNC_O_SPDIF_OUT (MTK_PIN_NO(11) | 2) +#define PINMUX_GPIO11__FUNC_O_I2SO1_D0 (MTK_PIN_NO(11) | 3) +#define PINMUX_GPIO11__FUNC_I0_DMIC2_DAT_R (MTK_PIN_NO(11) | 4) +#define PINMUX_GPIO11__FUNC_I0_DVFSRC_EXT_REQ (MTK_PIN_NO(11) | 5) +#define PINMUX_GPIO11__FUNC_O_CMVREF6 (MTK_PIN_NO(11) | 6) +#define PINMUX_GPIO11__FUNC_B0_DBG_MON_A10 (MTK_PIN_NO(11) | 7) + +#define PINMUX_GPIO12__FUNC_B_GPIO12 (MTK_PIN_NO(12) | 0) +#define PINMUX_GPIO12__FUNC_B0_TP_GPIO4_AO (MTK_PIN_NO(12) | 1) +#define PINMUX_GPIO12__FUNC_O_SPIM4_CSB (MTK_PIN_NO(12) | 2) +#define PINMUX_GPIO12__FUNC_B1_JTMS_SEL3 (MTK_PIN_NO(12) | 3) +#define PINMUX_GPIO12__FUNC_B1_APU_JTAG_TMS (MTK_PIN_NO(12) | 4) +#define PINMUX_GPIO12__FUNC_I0_VPU_UDI_TMS (MTK_PIN_NO(12) | 5) +#define PINMUX_GPIO12__FUNC_I0_IPU_JTAG_TMS (MTK_PIN_NO(12) | 6) +#define PINMUX_GPIO12__FUNC_I0_HDMITX20_HTPLG (MTK_PIN_NO(12) | 7) + +#define PINMUX_GPIO13__FUNC_B_GPIO13 (MTK_PIN_NO(13) | 0) +#define PINMUX_GPIO13__FUNC_B0_TP_GPIO5_AO (MTK_PIN_NO(13) | 1) +#define PINMUX_GPIO13__FUNC_O_SPIM4_CLK (MTK_PIN_NO(13) | 2) +#define PINMUX_GPIO13__FUNC_I0_JTCK_SEL3 (MTK_PIN_NO(13) | 3) +#define PINMUX_GPIO13__FUNC_I0_APU_JTAG_TCK (MTK_PIN_NO(13) | 4) +#define PINMUX_GPIO13__FUNC_I0_VPU_UDI_TCK (MTK_PIN_NO(13) | 5) +#define PINMUX_GPIO13__FUNC_I0_IPU_JTAG_TCK (MTK_PIN_NO(13) | 6) +#define PINMUX_GPIO13__FUNC_B1_HDMITX20_CEC (MTK_PIN_NO(13) | 7) + +#define PINMUX_GPIO14__FUNC_B_GPIO14 (MTK_PIN_NO(14) | 0) +#define PINMUX_GPIO14__FUNC_B0_TP_GPIO6_AO (MTK_PIN_NO(14) | 1) +#define PINMUX_GPIO14__FUNC_B0_SPIM4_MOSI (MTK_PIN_NO(14) | 2) +#define PINMUX_GPIO14__FUNC_I1_JTDI_SEL3 (MTK_PIN_NO(14) | 3) +#define PINMUX_GPIO14__FUNC_I1_APU_JTAG_TDI (MTK_PIN_NO(14) | 4) +#define PINMUX_GPIO14__FUNC_I0_VPU_UDI_TDI (MTK_PIN_NO(14) | 5) +#define PINMUX_GPIO14__FUNC_I0_IPU_JTAG_TDI (MTK_PIN_NO(14) | 6) +#define PINMUX_GPIO14__FUNC_B1_HDMITX20_SCL (MTK_PIN_NO(14) | 7) + +#define PINMUX_GPIO15__FUNC_B_GPIO15 (MTK_PIN_NO(15) | 0) +#define PINMUX_GPIO15__FUNC_B0_TP_GPIO7_AO (MTK_PIN_NO(15) | 1) +#define PINMUX_GPIO15__FUNC_B0_SPIM4_MISO (MTK_PIN_NO(15) | 2) +#define PINMUX_GPIO15__FUNC_O_JTDO_SEL3 (MTK_PIN_NO(15) | 3) +#define PINMUX_GPIO15__FUNC_O_APU_JTAG_TDO (MTK_PIN_NO(15) | 4) +#define PINMUX_GPIO15__FUNC_O_VPU_UDI_TDO (MTK_PIN_NO(15) | 5) +#define PINMUX_GPIO15__FUNC_O_IPU_JTAG_TDO (MTK_PIN_NO(15) | 6) +#define PINMUX_GPIO15__FUNC_B1_HDMITX20_SDA (MTK_PIN_NO(15) | 7) + +#define PINMUX_GPIO16__FUNC_B_GPIO16 (MTK_PIN_NO(16) | 0) +#define PINMUX_GPIO16__FUNC_B0_TP_GPIO0_AO (MTK_PIN_NO(16) | 1) +#define PINMUX_GPIO16__FUNC_O_UTXD3 (MTK_PIN_NO(16) | 2) +#define PINMUX_GPIO16__FUNC_I1_JTRSTn_SEL3 (MTK_PIN_NO(16) | 3) +#define PINMUX_GPIO16__FUNC_I0_APU_JTAG_TRST (MTK_PIN_NO(16) | 4) +#define PINMUX_GPIO16__FUNC_I0_VPU_UDI_NTRST (MTK_PIN_NO(16) | 5) +#define PINMUX_GPIO16__FUNC_I0_IPU_JTAG_TRST (MTK_PIN_NO(16) | 6) +#define PINMUX_GPIO16__FUNC_O_HDMITX20_PWR5V (MTK_PIN_NO(16) | 7) + +#define PINMUX_GPIO17__FUNC_B_GPIO17 (MTK_PIN_NO(17) | 0) +#define PINMUX_GPIO17__FUNC_B0_TP_GPIO1_AO (MTK_PIN_NO(17) | 1) +#define PINMUX_GPIO17__FUNC_I1_URXD3 (MTK_PIN_NO(17) | 2) +#define PINMUX_GPIO17__FUNC_O_CMFLASH2 (MTK_PIN_NO(17) | 3) +#define PINMUX_GPIO17__FUNC_I0_EDP_TX_HPD (MTK_PIN_NO(17) | 4) +#define PINMUX_GPIO17__FUNC_I0_DVFSRC_EXT_REQ (MTK_PIN_NO(17) | 5) +#define PINMUX_GPIO17__FUNC_O_CMVREF7 (MTK_PIN_NO(17) | 6) +#define PINMUX_GPIO17__FUNC_B0_MD32_0_GPIO1 (MTK_PIN_NO(17) | 7) + +#define PINMUX_GPIO18__FUNC_B_GPIO18 (MTK_PIN_NO(18) | 0) +#define PINMUX_GPIO18__FUNC_B0_TP_GPIO2_AO (MTK_PIN_NO(18) | 1) +#define PINMUX_GPIO18__FUNC_O_CMFLASH0 (MTK_PIN_NO(18) | 2) +#define PINMUX_GPIO18__FUNC_O_CMVREF4 (MTK_PIN_NO(18) | 3) +#define PINMUX_GPIO18__FUNC_B0_TDMIN_MCK (MTK_PIN_NO(18) | 4) +#define PINMUX_GPIO18__FUNC_O_UTXD1 (MTK_PIN_NO(18) | 5) +#define PINMUX_GPIO18__FUNC_O_TP_UTXD1_AO (MTK_PIN_NO(18) | 6) +#define PINMUX_GPIO18__FUNC_B0_DBG_MON_A11 (MTK_PIN_NO(18) | 7) + +#define PINMUX_GPIO19__FUNC_B_GPIO19 (MTK_PIN_NO(19) | 0) +#define PINMUX_GPIO19__FUNC_B0_TP_GPIO3_AO (MTK_PIN_NO(19) | 1) +#define PINMUX_GPIO19__FUNC_O_CMFLASH1 (MTK_PIN_NO(19) | 2) +#define PINMUX_GPIO19__FUNC_O_CMVREF5 (MTK_PIN_NO(19) | 3) +#define PINMUX_GPIO19__FUNC_B0_TDMIN_BCK (MTK_PIN_NO(19) | 4) +#define PINMUX_GPIO19__FUNC_I1_URXD1 (MTK_PIN_NO(19) | 5) +#define PINMUX_GPIO19__FUNC_I1_TP_URXD1_AO (MTK_PIN_NO(19) | 6) +#define PINMUX_GPIO19__FUNC_B0_DBG_MON_A12 (MTK_PIN_NO(19) | 7) + +#define PINMUX_GPIO20__FUNC_B_GPIO20 (MTK_PIN_NO(20) | 0) +#define PINMUX_GPIO20__FUNC_B0_TP_GPIO4_AO (MTK_PIN_NO(20) | 1) +#define PINMUX_GPIO20__FUNC_O_CMFLASH2 (MTK_PIN_NO(20) | 2) +#define PINMUX_GPIO20__FUNC_O_CLKM2 (MTK_PIN_NO(20) | 3) +#define PINMUX_GPIO20__FUNC_B0_TDMIN_LRCK (MTK_PIN_NO(20) | 4) +#define PINMUX_GPIO20__FUNC_O_URTS1 (MTK_PIN_NO(20) | 5) +#define PINMUX_GPIO20__FUNC_O_TP_URTS1_AO (MTK_PIN_NO(20) | 6) +#define PINMUX_GPIO20__FUNC_B0_DBG_MON_A13 (MTK_PIN_NO(20) | 7) + +#define PINMUX_GPIO21__FUNC_B_GPIO21 (MTK_PIN_NO(21) | 0) +#define PINMUX_GPIO21__FUNC_B0_TP_GPIO5_AO (MTK_PIN_NO(21) | 1) +#define PINMUX_GPIO21__FUNC_O_CMFLASH3 (MTK_PIN_NO(21) | 2) +#define PINMUX_GPIO21__FUNC_O_CLKM3 (MTK_PIN_NO(21) | 3) +#define PINMUX_GPIO21__FUNC_I0_TDMIN_DI (MTK_PIN_NO(21) | 4) +#define PINMUX_GPIO21__FUNC_I1_UCTS1 (MTK_PIN_NO(21) | 5) +#define PINMUX_GPIO21__FUNC_I1_TP_UCTS1_AO (MTK_PIN_NO(21) | 6) +#define PINMUX_GPIO21__FUNC_B0_DBG_MON_A14 (MTK_PIN_NO(21) | 7) + +#define PINMUX_GPIO22__FUNC_B_GPIO22 (MTK_PIN_NO(22) | 0) +#define PINMUX_GPIO22__FUNC_O_CMMCLK0 (MTK_PIN_NO(22) | 1) +#define PINMUX_GPIO22__FUNC_B0_TP_GPIO6_AO (MTK_PIN_NO(22) | 5) +#define PINMUX_GPIO22__FUNC_B0_DBG_MON_A15 (MTK_PIN_NO(22) | 7) + +#define PINMUX_GPIO23__FUNC_B_GPIO23 (MTK_PIN_NO(23) | 0) +#define PINMUX_GPIO23__FUNC_O_CMMCLK1 (MTK_PIN_NO(23) | 1) +#define PINMUX_GPIO23__FUNC_O_PWM_2 (MTK_PIN_NO(23) | 3) +#define PINMUX_GPIO23__FUNC_B1_PCIE_PHY_I2C_SCL (MTK_PIN_NO(23) | 4) +#define PINMUX_GPIO23__FUNC_B0_TP_GPIO7_AO (MTK_PIN_NO(23) | 5) +#define PINMUX_GPIO23__FUNC_I0_DP_TX_HPD (MTK_PIN_NO(23) | 6) +#define PINMUX_GPIO23__FUNC_B0_DBG_MON_A16 (MTK_PIN_NO(23) | 7) + +#define PINMUX_GPIO24__FUNC_B_GPIO24 (MTK_PIN_NO(24) | 0) +#define PINMUX_GPIO24__FUNC_O_CMMCLK2 (MTK_PIN_NO(24) | 1) +#define PINMUX_GPIO24__FUNC_O_PWM_3 (MTK_PIN_NO(24) | 3) +#define PINMUX_GPIO24__FUNC_B1_PCIE_PHY_I2C_SDA (MTK_PIN_NO(24) | 4) +#define PINMUX_GPIO24__FUNC_I0_DVFSRC_EXT_REQ (MTK_PIN_NO(24) | 5) +#define PINMUX_GPIO24__FUNC_I0_EDP_TX_HPD (MTK_PIN_NO(24) | 6) +#define PINMUX_GPIO24__FUNC_B0_MD32_0_GPIO2 (MTK_PIN_NO(24) | 7) + +#define PINMUX_GPIO25__FUNC_B_GPIO25 (MTK_PIN_NO(25) | 0) +#define PINMUX_GPIO25__FUNC_O_LCM_RST (MTK_PIN_NO(25) | 1) +#define PINMUX_GPIO25__FUNC_O_LCM1_RST (MTK_PIN_NO(25) | 2) +#define PINMUX_GPIO25__FUNC_I0_DP_TX_HPD (MTK_PIN_NO(25) | 3) + +#define PINMUX_GPIO26__FUNC_B_GPIO26 (MTK_PIN_NO(26) | 0) +#define PINMUX_GPIO26__FUNC_I0_DSI_TE (MTK_PIN_NO(26) | 1) +#define PINMUX_GPIO26__FUNC_I0_DSI1_TE (MTK_PIN_NO(26) | 2) +#define PINMUX_GPIO26__FUNC_I0_EDP_TX_HPD (MTK_PIN_NO(26) | 3) + +#define PINMUX_GPIO27__FUNC_B_GPIO27 (MTK_PIN_NO(27) | 0) +#define PINMUX_GPIO27__FUNC_O_LCM1_RST (MTK_PIN_NO(27) | 1) +#define PINMUX_GPIO27__FUNC_O_LCM_RST (MTK_PIN_NO(27) | 2) +#define PINMUX_GPIO27__FUNC_I0_DP_TX_HPD (MTK_PIN_NO(27) | 3) +#define PINMUX_GPIO27__FUNC_O_CMVREF2 (MTK_PIN_NO(27) | 4) +#define PINMUX_GPIO27__FUNC_O_mbistwriteen_trigger (MTK_PIN_NO(27) | 5) +#define PINMUX_GPIO27__FUNC_O_PWM_2 (MTK_PIN_NO(27) | 6) +#define PINMUX_GPIO27__FUNC_B0_DBG_MON_A17 (MTK_PIN_NO(27) | 7) + +#define PINMUX_GPIO28__FUNC_B_GPIO28 (MTK_PIN_NO(28) | 0) +#define PINMUX_GPIO28__FUNC_I0_DSI1_TE (MTK_PIN_NO(28) | 1) +#define PINMUX_GPIO28__FUNC_I0_DSI_TE (MTK_PIN_NO(28) | 2) +#define PINMUX_GPIO28__FUNC_I0_EDP_TX_HPD (MTK_PIN_NO(28) | 3) +#define PINMUX_GPIO28__FUNC_O_CMVREF3 (MTK_PIN_NO(28) | 4) +#define PINMUX_GPIO28__FUNC_O_mbistreaden_trigger (MTK_PIN_NO(28) | 5) +#define PINMUX_GPIO28__FUNC_O_PWM_3 (MTK_PIN_NO(28) | 6) +#define PINMUX_GPIO28__FUNC_B0_DBG_MON_A18 (MTK_PIN_NO(28) | 7) + +#define PINMUX_GPIO29__FUNC_B_GPIO29 (MTK_PIN_NO(29) | 0) +#define PINMUX_GPIO29__FUNC_O_DISP_PWM0 (MTK_PIN_NO(29) | 1) +#define PINMUX_GPIO29__FUNC_O_DISP_PWM1 (MTK_PIN_NO(29) | 2) + +#define PINMUX_GPIO30__FUNC_B_GPIO30 (MTK_PIN_NO(30) | 0) +#define PINMUX_GPIO30__FUNC_O_DISP_PWM1 (MTK_PIN_NO(30) | 1) +#define PINMUX_GPIO30__FUNC_O_DISP_PWM0 (MTK_PIN_NO(30) | 2) +#define PINMUX_GPIO30__FUNC_O_CMFLASH3 (MTK_PIN_NO(30) | 3) +#define PINMUX_GPIO30__FUNC_O_PWM_1 (MTK_PIN_NO(30) | 4) +#define PINMUX_GPIO30__FUNC_B0_DBG_MON_A19 (MTK_PIN_NO(30) | 7) + +#define PINMUX_GPIO31__FUNC_B_GPIO31 (MTK_PIN_NO(31) | 0) +#define PINMUX_GPIO31__FUNC_O_UTXD0 (MTK_PIN_NO(31) | 1) +#define PINMUX_GPIO31__FUNC_O_TP_UTXD1_AO (MTK_PIN_NO(31) | 2) +#define PINMUX_GPIO31__FUNC_O_ADSP_UTXD0 (MTK_PIN_NO(31) | 3) +#define PINMUX_GPIO31__FUNC_O_TP_UTXD2_AO (MTK_PIN_NO(31) | 4) +#define PINMUX_GPIO31__FUNC_O_MD32_0_TXD (MTK_PIN_NO(31) | 5) +#define PINMUX_GPIO31__FUNC_O_MD32_1_TXD (MTK_PIN_NO(31) | 6) +#define PINMUX_GPIO31__FUNC_O_SSPM_UTXD_AO (MTK_PIN_NO(31) | 7) + +#define PINMUX_GPIO32__FUNC_B_GPIO32 (MTK_PIN_NO(32) | 0) +#define PINMUX_GPIO32__FUNC_I1_URXD0 (MTK_PIN_NO(32) | 1) +#define PINMUX_GPIO32__FUNC_I1_TP_URXD1_AO (MTK_PIN_NO(32) | 2) +#define PINMUX_GPIO32__FUNC_I1_ADSP_URXD0 (MTK_PIN_NO(32) | 3) +#define PINMUX_GPIO32__FUNC_I1_TP_URXD2_AO (MTK_PIN_NO(32) | 4) +#define PINMUX_GPIO32__FUNC_I1_MD32_0_RXD (MTK_PIN_NO(32) | 5) +#define PINMUX_GPIO32__FUNC_I1_MD32_1_RXD (MTK_PIN_NO(32) | 6) +#define PINMUX_GPIO32__FUNC_I1_SSPM_URXD_AO (MTK_PIN_NO(32) | 7) + +#define PINMUX_GPIO33__FUNC_B_GPIO33 (MTK_PIN_NO(33) | 0) +#define PINMUX_GPIO33__FUNC_O_UTXD1 (MTK_PIN_NO(33) | 1) +#define PINMUX_GPIO33__FUNC_O_URTS2 (MTK_PIN_NO(33) | 2) +#define PINMUX_GPIO33__FUNC_O_ADSP_UTXD0 (MTK_PIN_NO(33) | 3) +#define PINMUX_GPIO33__FUNC_O_TP_UTXD1_AO (MTK_PIN_NO(33) | 4) +#define PINMUX_GPIO33__FUNC_O_mbistwriteen_trigger (MTK_PIN_NO(33) | 5) +#define PINMUX_GPIO33__FUNC_O_MD32_0_TXD (MTK_PIN_NO(33) | 6) +#define PINMUX_GPIO33__FUNC_O_SSPM_UTXD_AO (MTK_PIN_NO(33) | 7) + +#define PINMUX_GPIO34__FUNC_B_GPIO34 (MTK_PIN_NO(34) | 0) +#define PINMUX_GPIO34__FUNC_I1_URXD1 (MTK_PIN_NO(34) | 1) +#define PINMUX_GPIO34__FUNC_I1_UCTS2 (MTK_PIN_NO(34) | 2) +#define PINMUX_GPIO34__FUNC_I1_ADSP_URXD0 (MTK_PIN_NO(34) | 3) +#define PINMUX_GPIO34__FUNC_I1_TP_URXD1_AO (MTK_PIN_NO(34) | 4) +#define PINMUX_GPIO34__FUNC_O_mbistreaden_trigger (MTK_PIN_NO(34) | 5) +#define PINMUX_GPIO34__FUNC_I1_MD32_0_RXD (MTK_PIN_NO(34) | 6) +#define PINMUX_GPIO34__FUNC_I1_SSPM_URXD_AO (MTK_PIN_NO(34) | 7) + +#define PINMUX_GPIO35__FUNC_B_GPIO35 (MTK_PIN_NO(35) | 0) +#define PINMUX_GPIO35__FUNC_O_UTXD2 (MTK_PIN_NO(35) | 1) +#define PINMUX_GPIO35__FUNC_O_URTS1 (MTK_PIN_NO(35) | 2) +#define PINMUX_GPIO35__FUNC_O_ADSP_UTXD0 (MTK_PIN_NO(35) | 3) +#define PINMUX_GPIO35__FUNC_O_TP_URTS1_AO (MTK_PIN_NO(35) | 4) +#define PINMUX_GPIO35__FUNC_O_TP_UTXD2_AO (MTK_PIN_NO(35) | 5) +#define PINMUX_GPIO35__FUNC_O_MD32_1_TXD (MTK_PIN_NO(35) | 6) +#define PINMUX_GPIO35__FUNC_B0_DBG_MON_A20 (MTK_PIN_NO(35) | 7) + +#define PINMUX_GPIO36__FUNC_B_GPIO36 (MTK_PIN_NO(36) | 0) +#define PINMUX_GPIO36__FUNC_I1_URXD2 (MTK_PIN_NO(36) | 1) +#define PINMUX_GPIO36__FUNC_I1_UCTS1 (MTK_PIN_NO(36) | 2) +#define PINMUX_GPIO36__FUNC_I1_ADSP_URXD0 (MTK_PIN_NO(36) | 3) +#define PINMUX_GPIO36__FUNC_I1_TP_UCTS1_AO (MTK_PIN_NO(36) | 4) +#define PINMUX_GPIO36__FUNC_I1_TP_URXD2_AO (MTK_PIN_NO(36) | 5) +#define PINMUX_GPIO36__FUNC_I1_MD32_1_RXD (MTK_PIN_NO(36) | 6) +#define PINMUX_GPIO36__FUNC_B0_DBG_MON_A21 (MTK_PIN_NO(36) | 7) + +#define PINMUX_GPIO37__FUNC_B_GPIO37 (MTK_PIN_NO(37) | 0) +#define PINMUX_GPIO37__FUNC_B1_JTMS_SEL1 (MTK_PIN_NO(37) | 1) +#define PINMUX_GPIO37__FUNC_I0_UDI_TMS (MTK_PIN_NO(37) | 2) +#define PINMUX_GPIO37__FUNC_I1_SPM_JTAG_TMS (MTK_PIN_NO(37) | 3) +#define PINMUX_GPIO37__FUNC_I1_ADSP_JTAG0_TMS (MTK_PIN_NO(37) | 4) +#define PINMUX_GPIO37__FUNC_I1_SCP_JTAG0_TMS (MTK_PIN_NO(37) | 5) +#define PINMUX_GPIO37__FUNC_I1_CCU0_JTAG_TMS (MTK_PIN_NO(37) | 6) +#define PINMUX_GPIO37__FUNC_I1_MCUPM_JTAG_TMS (MTK_PIN_NO(37) | 7) + +#define PINMUX_GPIO38__FUNC_B_GPIO38 (MTK_PIN_NO(38) | 0) +#define PINMUX_GPIO38__FUNC_I0_JTCK_SEL1 (MTK_PIN_NO(38) | 1) +#define PINMUX_GPIO38__FUNC_I0_UDI_TCK (MTK_PIN_NO(38) | 2) +#define PINMUX_GPIO38__FUNC_I1_SPM_JTAG_TCK (MTK_PIN_NO(38) | 3) +#define PINMUX_GPIO38__FUNC_I0_ADSP_JTAG0_TCK (MTK_PIN_NO(38) | 4) +#define PINMUX_GPIO38__FUNC_I1_SCP_JTAG0_TCK (MTK_PIN_NO(38) | 5) +#define PINMUX_GPIO38__FUNC_I1_CCU0_JTAG_TCK (MTK_PIN_NO(38) | 6) +#define PINMUX_GPIO38__FUNC_I1_MCUPM_JTAG_TCK (MTK_PIN_NO(38) | 7) + +#define PINMUX_GPIO39__FUNC_B_GPIO39 (MTK_PIN_NO(39) | 0) +#define PINMUX_GPIO39__FUNC_I1_JTDI_SEL1 (MTK_PIN_NO(39) | 1) +#define PINMUX_GPIO39__FUNC_I0_UDI_TDI (MTK_PIN_NO(39) | 2) +#define PINMUX_GPIO39__FUNC_I1_SPM_JTAG_TDI (MTK_PIN_NO(39) | 3) +#define PINMUX_GPIO39__FUNC_I1_ADSP_JTAG0_TDI (MTK_PIN_NO(39) | 4) +#define PINMUX_GPIO39__FUNC_I1_SCP_JTAG0_TDI (MTK_PIN_NO(39) | 5) +#define PINMUX_GPIO39__FUNC_I1_CCU0_JTAG_TDI (MTK_PIN_NO(39) | 6) +#define PINMUX_GPIO39__FUNC_I1_MCUPM_JTAG_TDI (MTK_PIN_NO(39) | 7) + +#define PINMUX_GPIO40__FUNC_B_GPIO40 (MTK_PIN_NO(40) | 0) +#define PINMUX_GPIO40__FUNC_O_JTDO_SEL1 (MTK_PIN_NO(40) | 1) +#define PINMUX_GPIO40__FUNC_O_UDI_TDO (MTK_PIN_NO(40) | 2) +#define PINMUX_GPIO40__FUNC_O_SPM_JTAG_TDO (MTK_PIN_NO(40) | 3) +#define PINMUX_GPIO40__FUNC_O_ADSP_JTAG0_TDO (MTK_PIN_NO(40) | 4) +#define PINMUX_GPIO40__FUNC_O_SCP_JTAG0_TDO (MTK_PIN_NO(40) | 5) +#define PINMUX_GPIO40__FUNC_O_CCU0_JTAG_TDO (MTK_PIN_NO(40) | 6) +#define PINMUX_GPIO40__FUNC_O_MCUPM_JTAG_TDO (MTK_PIN_NO(40) | 7) + +#define PINMUX_GPIO41__FUNC_B_GPIO41 (MTK_PIN_NO(41) | 0) +#define PINMUX_GPIO41__FUNC_I1_JTRSTn_SEL1 (MTK_PIN_NO(41) | 1) +#define PINMUX_GPIO41__FUNC_I0_UDI_NTRST (MTK_PIN_NO(41) | 2) +#define PINMUX_GPIO41__FUNC_I0_SPM_JTAG_TRSTN (MTK_PIN_NO(41) | 3) +#define PINMUX_GPIO41__FUNC_I1_ADSP_JTAG0_TRSTN (MTK_PIN_NO(41) | 4) +#define PINMUX_GPIO41__FUNC_I0_SCP_JTAG0_TRSTN (MTK_PIN_NO(41) | 5) +#define PINMUX_GPIO41__FUNC_I1_CCU0_JTAG_TRST (MTK_PIN_NO(41) | 6) +#define PINMUX_GPIO41__FUNC_I0_MCUPM_JTAG_TRSTN (MTK_PIN_NO(41) | 7) + +#define PINMUX_GPIO42__FUNC_B_GPIO42 (MTK_PIN_NO(42) | 0) +#define PINMUX_GPIO42__FUNC_B1_KPCOL0 (MTK_PIN_NO(42) | 1) + +#define PINMUX_GPIO43__FUNC_B_GPIO43 (MTK_PIN_NO(43) | 0) +#define PINMUX_GPIO43__FUNC_B1_KPCOL1 (MTK_PIN_NO(43) | 1) +#define PINMUX_GPIO43__FUNC_I0_DP_TX_HPD (MTK_PIN_NO(43) | 2) +#define PINMUX_GPIO43__FUNC_O_CMFLASH2 (MTK_PIN_NO(43) | 3) +#define PINMUX_GPIO43__FUNC_I0_DVFSRC_EXT_REQ (MTK_PIN_NO(43) | 4) +#define PINMUX_GPIO43__FUNC_O_mbistwriteen_trigger (MTK_PIN_NO(43) | 7) + +#define PINMUX_GPIO44__FUNC_B_GPIO44 (MTK_PIN_NO(44) | 0) +#define PINMUX_GPIO44__FUNC_B1_KPROW0 (MTK_PIN_NO(44) | 1) + +#define PINMUX_GPIO45__FUNC_B_GPIO45 (MTK_PIN_NO(45) | 0) +#define PINMUX_GPIO45__FUNC_B1_KPROW1 (MTK_PIN_NO(45) | 1) +#define PINMUX_GPIO45__FUNC_I0_EDP_TX_HPD (MTK_PIN_NO(45) | 2) +#define PINMUX_GPIO45__FUNC_O_CMFLASH3 (MTK_PIN_NO(45) | 3) +#define PINMUX_GPIO45__FUNC_B0_I2SIN_MCK (MTK_PIN_NO(45) | 4) +#define PINMUX_GPIO45__FUNC_O_mbistreaden_trigger (MTK_PIN_NO(45) | 7) + +#define PINMUX_GPIO46__FUNC_B_GPIO46 (MTK_PIN_NO(46) | 0) +#define PINMUX_GPIO46__FUNC_I0_DP_TX_HPD (MTK_PIN_NO(46) | 1) +#define PINMUX_GPIO46__FUNC_O_PWM_0 (MTK_PIN_NO(46) | 2) +#define PINMUX_GPIO46__FUNC_I0_VBUSVALID_2P (MTK_PIN_NO(46) | 3) +#define PINMUX_GPIO46__FUNC_B0_DBG_MON_A22 (MTK_PIN_NO(46) | 7) + +#define PINMUX_GPIO47__FUNC_B_GPIO47 (MTK_PIN_NO(47) | 0) +#define PINMUX_GPIO47__FUNC_I1_WAKEN (MTK_PIN_NO(47) | 1) +#define PINMUX_GPIO47__FUNC_O_GDU_TROOPS_DET0 (MTK_PIN_NO(47) | 6) + +#define PINMUX_GPIO48__FUNC_B_GPIO48 (MTK_PIN_NO(48) | 0) +#define PINMUX_GPIO48__FUNC_O_PERSTN (MTK_PIN_NO(48) | 1) +#define PINMUX_GPIO48__FUNC_O_GDU_TROOPS_DET1 (MTK_PIN_NO(48) | 6) + +#define PINMUX_GPIO49__FUNC_B_GPIO49 (MTK_PIN_NO(49) | 0) +#define PINMUX_GPIO49__FUNC_B1_CLKREQN (MTK_PIN_NO(49) | 1) +#define PINMUX_GPIO49__FUNC_O_GDU_TROOPS_DET2 (MTK_PIN_NO(49) | 6) + +#define PINMUX_GPIO50__FUNC_B_GPIO50 (MTK_PIN_NO(50) | 0) +#define PINMUX_GPIO50__FUNC_O_HDMITX20_PWR5V (MTK_PIN_NO(50) | 1) +#define PINMUX_GPIO50__FUNC_I1_IDDIG_1P (MTK_PIN_NO(50) | 3) +#define PINMUX_GPIO50__FUNC_I1_SCP_JTAG1_TMS (MTK_PIN_NO(50) | 4) +#define PINMUX_GPIO50__FUNC_I1_SSPM_JTAG_TMS (MTK_PIN_NO(50) | 5) +#define PINMUX_GPIO50__FUNC_I1_MD32_0_JTAG_TMS (MTK_PIN_NO(50) | 6) +#define PINMUX_GPIO50__FUNC_I1_MD32_1_JTAG_TMS (MTK_PIN_NO(50) | 7) + +#define PINMUX_GPIO51__FUNC_B_GPIO51 (MTK_PIN_NO(51) | 0) +#define PINMUX_GPIO51__FUNC_I0_HDMITX20_HTPLG (MTK_PIN_NO(51) | 1) +#define PINMUX_GPIO51__FUNC_I0_EDP_TX_HPD (MTK_PIN_NO(51) | 2) +#define PINMUX_GPIO51__FUNC_O_USB_DRVVBUS_1P (MTK_PIN_NO(51) | 3) +#define PINMUX_GPIO51__FUNC_I1_SCP_JTAG1_TCK (MTK_PIN_NO(51) | 4) +#define PINMUX_GPIO51__FUNC_I1_SSPM_JTAG_TCK (MTK_PIN_NO(51) | 5) +#define PINMUX_GPIO51__FUNC_I1_MD32_0_JTAG_TCK (MTK_PIN_NO(51) | 6) +#define PINMUX_GPIO51__FUNC_I1_MD32_1_JTAG_TCK (MTK_PIN_NO(51) | 7) + +#define PINMUX_GPIO52__FUNC_B_GPIO52 (MTK_PIN_NO(52) | 0) +#define PINMUX_GPIO52__FUNC_B1_HDMITX20_CEC (MTK_PIN_NO(52) | 1) +#define PINMUX_GPIO52__FUNC_I0_VBUSVALID_1P (MTK_PIN_NO(52) | 3) +#define PINMUX_GPIO52__FUNC_I1_SCP_JTAG1_TDI (MTK_PIN_NO(52) | 4) +#define PINMUX_GPIO52__FUNC_I1_SSPM_JTAG_TDI (MTK_PIN_NO(52) | 5) +#define PINMUX_GPIO52__FUNC_I1_MD32_0_JTAG_TDI (MTK_PIN_NO(52) | 6) +#define PINMUX_GPIO52__FUNC_I1_MD32_1_JTAG_TDI (MTK_PIN_NO(52) | 7) + +#define PINMUX_GPIO53__FUNC_B_GPIO53 (MTK_PIN_NO(53) | 0) +#define PINMUX_GPIO53__FUNC_B1_HDMITX20_SCL (MTK_PIN_NO(53) | 1) +#define PINMUX_GPIO53__FUNC_I1_IDDIG_2P (MTK_PIN_NO(53) | 3) +#define PINMUX_GPIO53__FUNC_O_SCP_JTAG1_TDO (MTK_PIN_NO(53) | 4) +#define PINMUX_GPIO53__FUNC_O_SSPM_JTAG_TDO (MTK_PIN_NO(53) | 5) +#define PINMUX_GPIO53__FUNC_O_MD32_0_JTAG_TDO (MTK_PIN_NO(53) | 6) +#define PINMUX_GPIO53__FUNC_O_MD32_1_JTAG_TDO (MTK_PIN_NO(53) | 7) + +#define PINMUX_GPIO54__FUNC_B_GPIO54 (MTK_PIN_NO(54) | 0) +#define PINMUX_GPIO54__FUNC_B1_HDMITX20_SDA (MTK_PIN_NO(54) | 1) +#define PINMUX_GPIO54__FUNC_O_USB_DRVVBUS_2P (MTK_PIN_NO(54) | 3) +#define PINMUX_GPIO54__FUNC_I0_SCP_JTAG1_TRSTN (MTK_PIN_NO(54) | 4) +#define PINMUX_GPIO54__FUNC_I0_SSPM_JTAG_TRSTN (MTK_PIN_NO(54) | 5) +#define PINMUX_GPIO54__FUNC_I1_MD32_0_JTAG_TRST (MTK_PIN_NO(54) | 6) +#define PINMUX_GPIO54__FUNC_I1_MD32_1_JTAG_TRST (MTK_PIN_NO(54) | 7) + +#define PINMUX_GPIO55__FUNC_B_GPIO55 (MTK_PIN_NO(55) | 0) +#define PINMUX_GPIO55__FUNC_B1_SCL0 (MTK_PIN_NO(55) | 1) +#define PINMUX_GPIO55__FUNC_B1_SCP_SCL0 (MTK_PIN_NO(55) | 2) +#define PINMUX_GPIO55__FUNC_B1_SCP_SCL1 (MTK_PIN_NO(55) | 3) +#define PINMUX_GPIO55__FUNC_B1_PCIE_PHY_I2C_SCL (MTK_PIN_NO(55) | 4) + +#define PINMUX_GPIO56__FUNC_B_GPIO56 (MTK_PIN_NO(56) | 0) +#define PINMUX_GPIO56__FUNC_B1_SDA0 (MTK_PIN_NO(56) | 1) +#define PINMUX_GPIO56__FUNC_B1_SCP_SDA0 (MTK_PIN_NO(56) | 2) +#define PINMUX_GPIO56__FUNC_B1_SCP_SDA1 (MTK_PIN_NO(56) | 3) +#define PINMUX_GPIO56__FUNC_B1_PCIE_PHY_I2C_SDA (MTK_PIN_NO(56) | 4) + +#define PINMUX_GPIO57__FUNC_B_GPIO57 (MTK_PIN_NO(57) | 0) +#define PINMUX_GPIO57__FUNC_B1_SCL1 (MTK_PIN_NO(57) | 1) + +#define PINMUX_GPIO58__FUNC_B_GPIO58 (MTK_PIN_NO(58) | 0) +#define PINMUX_GPIO58__FUNC_B1_SDA1 (MTK_PIN_NO(58) | 1) + +#define PINMUX_GPIO59__FUNC_B_GPIO59 (MTK_PIN_NO(59) | 0) +#define PINMUX_GPIO59__FUNC_B1_SCL2 (MTK_PIN_NO(59) | 1) +#define PINMUX_GPIO59__FUNC_B1_SCP_SCL0 (MTK_PIN_NO(59) | 2) +#define PINMUX_GPIO59__FUNC_B1_SCP_SCL1 (MTK_PIN_NO(59) | 3) + +#define PINMUX_GPIO60__FUNC_B_GPIO60 (MTK_PIN_NO(60) | 0) +#define PINMUX_GPIO60__FUNC_B1_SDA2 (MTK_PIN_NO(60) | 1) +#define PINMUX_GPIO60__FUNC_B1_SCP_SDA0 (MTK_PIN_NO(60) | 2) +#define PINMUX_GPIO60__FUNC_B1_SCP_SDA1 (MTK_PIN_NO(60) | 3) + +#define PINMUX_GPIO61__FUNC_B_GPIO61 (MTK_PIN_NO(61) | 0) +#define PINMUX_GPIO61__FUNC_B1_SCL3 (MTK_PIN_NO(61) | 1) +#define PINMUX_GPIO61__FUNC_B1_SCP_SCL0 (MTK_PIN_NO(61) | 2) +#define PINMUX_GPIO61__FUNC_B1_SCP_SCL1 (MTK_PIN_NO(61) | 3) +#define PINMUX_GPIO61__FUNC_B1_PCIE_PHY_I2C_SCL (MTK_PIN_NO(61) | 4) + +#define PINMUX_GPIO62__FUNC_B_GPIO62 (MTK_PIN_NO(62) | 0) +#define PINMUX_GPIO62__FUNC_B1_SDA3 (MTK_PIN_NO(62) | 1) +#define PINMUX_GPIO62__FUNC_B1_SCP_SDA0 (MTK_PIN_NO(62) | 2) +#define PINMUX_GPIO62__FUNC_B1_SCP_SDA1 (MTK_PIN_NO(62) | 3) +#define PINMUX_GPIO62__FUNC_B1_PCIE_PHY_I2C_SDA (MTK_PIN_NO(62) | 4) + +#define PINMUX_GPIO63__FUNC_B_GPIO63 (MTK_PIN_NO(63) | 0) +#define PINMUX_GPIO63__FUNC_B1_SCL4 (MTK_PIN_NO(63) | 1) + +#define PINMUX_GPIO64__FUNC_B_GPIO64 (MTK_PIN_NO(64) | 0) +#define PINMUX_GPIO64__FUNC_B1_SDA4 (MTK_PIN_NO(64) | 1) + +#define PINMUX_GPIO65__FUNC_B_GPIO65 (MTK_PIN_NO(65) | 0) +#define PINMUX_GPIO65__FUNC_B1_SCL5 (MTK_PIN_NO(65) | 1) +#define PINMUX_GPIO65__FUNC_B1_SCP_SCL0 (MTK_PIN_NO(65) | 2) +#define PINMUX_GPIO65__FUNC_B1_SCP_SCL1 (MTK_PIN_NO(65) | 3) + +#define PINMUX_GPIO66__FUNC_B_GPIO66 (MTK_PIN_NO(66) | 0) +#define PINMUX_GPIO66__FUNC_B1_SDA5 (MTK_PIN_NO(66) | 1) +#define PINMUX_GPIO66__FUNC_B1_SCP_SDA0 (MTK_PIN_NO(66) | 2) +#define PINMUX_GPIO66__FUNC_B1_SCP_SDA1 (MTK_PIN_NO(66) | 3) + +#define PINMUX_GPIO67__FUNC_B_GPIO67 (MTK_PIN_NO(67) | 0) +#define PINMUX_GPIO67__FUNC_B1_SCL6 (MTK_PIN_NO(67) | 1) +#define PINMUX_GPIO67__FUNC_B1_SCP_SCL0 (MTK_PIN_NO(67) | 2) +#define PINMUX_GPIO67__FUNC_B1_SCP_SCL1 (MTK_PIN_NO(67) | 3) +#define PINMUX_GPIO67__FUNC_B1_PCIE_PHY_I2C_SCL (MTK_PIN_NO(67) | 4) + +#define PINMUX_GPIO68__FUNC_B_GPIO68 (MTK_PIN_NO(68) | 0) +#define PINMUX_GPIO68__FUNC_B1_SDA6 (MTK_PIN_NO(68) | 1) +#define PINMUX_GPIO68__FUNC_B1_SCP_SDA0 (MTK_PIN_NO(68) | 2) +#define PINMUX_GPIO68__FUNC_B1_SCP_SDA1 (MTK_PIN_NO(68) | 3) +#define PINMUX_GPIO68__FUNC_B1_PCIE_PHY_I2C_SDA (MTK_PIN_NO(68) | 4) + +#define PINMUX_GPIO69__FUNC_B_GPIO69 (MTK_PIN_NO(69) | 0) +#define PINMUX_GPIO69__FUNC_O_SPIM0_CSB (MTK_PIN_NO(69) | 1) +#define PINMUX_GPIO69__FUNC_O_SCP_SPI0_CS (MTK_PIN_NO(69) | 2) +#define PINMUX_GPIO69__FUNC_O_DMIC3_CLK (MTK_PIN_NO(69) | 3) +#define PINMUX_GPIO69__FUNC_B0_MD32_1_GPIO0 (MTK_PIN_NO(69) | 4) +#define PINMUX_GPIO69__FUNC_O_CMVREF0 (MTK_PIN_NO(69) | 5) +#define PINMUX_GPIO69__FUNC_O_GDU_SUM_TROOP0_0 (MTK_PIN_NO(69) | 6) +#define PINMUX_GPIO69__FUNC_B0_DBG_MON_A23 (MTK_PIN_NO(69) | 7) + +#define PINMUX_GPIO70__FUNC_B_GPIO70 (MTK_PIN_NO(70) | 0) +#define PINMUX_GPIO70__FUNC_O_SPIM0_CLK (MTK_PIN_NO(70) | 1) +#define PINMUX_GPIO70__FUNC_O_SCP_SPI0_CK (MTK_PIN_NO(70) | 2) +#define PINMUX_GPIO70__FUNC_I0_DMIC3_DAT (MTK_PIN_NO(70) | 3) +#define PINMUX_GPIO70__FUNC_B0_MD32_1_GPIO1 (MTK_PIN_NO(70) | 4) +#define PINMUX_GPIO70__FUNC_O_CMVREF1 (MTK_PIN_NO(70) | 5) +#define PINMUX_GPIO70__FUNC_O_GDU_SUM_TROOP0_1 (MTK_PIN_NO(70) | 6) +#define PINMUX_GPIO70__FUNC_B0_DBG_MON_A24 (MTK_PIN_NO(70) | 7) + +#define PINMUX_GPIO71__FUNC_B_GPIO71 (MTK_PIN_NO(71) | 0) +#define PINMUX_GPIO71__FUNC_B0_SPIM0_MOSI (MTK_PIN_NO(71) | 1) +#define PINMUX_GPIO71__FUNC_O_SCP_SPI0_MO (MTK_PIN_NO(71) | 2) +#define PINMUX_GPIO71__FUNC_I0_DMIC3_DAT_R (MTK_PIN_NO(71) | 3) +#define PINMUX_GPIO71__FUNC_B0_MD32_1_GPIO2 (MTK_PIN_NO(71) | 4) +#define PINMUX_GPIO71__FUNC_O_CMVREF2 (MTK_PIN_NO(71) | 5) +#define PINMUX_GPIO71__FUNC_O_GDU_SUM_TROOP0_2 (MTK_PIN_NO(71) | 6) +#define PINMUX_GPIO71__FUNC_B0_DBG_MON_A25 (MTK_PIN_NO(71) | 7) + +#define PINMUX_GPIO72__FUNC_B_GPIO72 (MTK_PIN_NO(72) | 0) +#define PINMUX_GPIO72__FUNC_B0_SPIM0_MISO (MTK_PIN_NO(72) | 1) +#define PINMUX_GPIO72__FUNC_I0_SCP_SPI0_MI (MTK_PIN_NO(72) | 2) +#define PINMUX_GPIO72__FUNC_O_DMIC4_CLK (MTK_PIN_NO(72) | 3) +#define PINMUX_GPIO72__FUNC_O_CMVREF3 (MTK_PIN_NO(72) | 5) +#define PINMUX_GPIO72__FUNC_O_GDU_SUM_TROOP1_0 (MTK_PIN_NO(72) | 6) +#define PINMUX_GPIO72__FUNC_B0_DBG_MON_A26 (MTK_PIN_NO(72) | 7) + +#define PINMUX_GPIO73__FUNC_B_GPIO73 (MTK_PIN_NO(73) | 0) +#define PINMUX_GPIO73__FUNC_B0_SPIM0_MIO2 (MTK_PIN_NO(73) | 1) +#define PINMUX_GPIO73__FUNC_O_UTXD3 (MTK_PIN_NO(73) | 2) +#define PINMUX_GPIO73__FUNC_I0_DMIC4_DAT (MTK_PIN_NO(73) | 3) +#define PINMUX_GPIO73__FUNC_O_CLKM0 (MTK_PIN_NO(73) | 4) +#define PINMUX_GPIO73__FUNC_O_CMVREF4 (MTK_PIN_NO(73) | 5) +#define PINMUX_GPIO73__FUNC_O_GDU_SUM_TROOP1_1 (MTK_PIN_NO(73) | 6) +#define PINMUX_GPIO73__FUNC_B0_DBG_MON_A27 (MTK_PIN_NO(73) | 7) + +#define PINMUX_GPIO74__FUNC_B_GPIO74 (MTK_PIN_NO(74) | 0) +#define PINMUX_GPIO74__FUNC_B0_SPIM0_MIO3 (MTK_PIN_NO(74) | 1) +#define PINMUX_GPIO74__FUNC_I1_URXD3 (MTK_PIN_NO(74) | 2) +#define PINMUX_GPIO74__FUNC_I0_DMIC4_DAT_R (MTK_PIN_NO(74) | 3) +#define PINMUX_GPIO74__FUNC_O_CLKM1 (MTK_PIN_NO(74) | 4) +#define PINMUX_GPIO74__FUNC_O_CMVREF5 (MTK_PIN_NO(74) | 5) +#define PINMUX_GPIO74__FUNC_O_GDU_SUM_TROOP1_2 (MTK_PIN_NO(74) | 6) +#define PINMUX_GPIO74__FUNC_B0_DBG_MON_A28 (MTK_PIN_NO(74) | 7) + +#define PINMUX_GPIO75__FUNC_B_GPIO75 (MTK_PIN_NO(75) | 0) +#define PINMUX_GPIO75__FUNC_O_SPIM1_CSB (MTK_PIN_NO(75) | 1) +#define PINMUX_GPIO75__FUNC_O_SCP_SPI1_A_CS (MTK_PIN_NO(75) | 2) +#define PINMUX_GPIO75__FUNC_B0_TDMIN_MCK (MTK_PIN_NO(75) | 3) +#define PINMUX_GPIO75__FUNC_B1_SCP_SCL0 (MTK_PIN_NO(75) | 4) +#define PINMUX_GPIO75__FUNC_O_CMVREF6 (MTK_PIN_NO(75) | 5) +#define PINMUX_GPIO75__FUNC_O_GDU_SUM_TROOP2_0 (MTK_PIN_NO(75) | 6) +#define PINMUX_GPIO75__FUNC_B0_DBG_MON_A29 (MTK_PIN_NO(75) | 7) + +#define PINMUX_GPIO76__FUNC_B_GPIO76 (MTK_PIN_NO(76) | 0) +#define PINMUX_GPIO76__FUNC_O_SPIM1_CLK (MTK_PIN_NO(76) | 1) +#define PINMUX_GPIO76__FUNC_O_SCP_SPI1_A_CK (MTK_PIN_NO(76) | 2) +#define PINMUX_GPIO76__FUNC_B0_TDMIN_BCK (MTK_PIN_NO(76) | 3) +#define PINMUX_GPIO76__FUNC_B1_SCP_SDA0 (MTK_PIN_NO(76) | 4) +#define PINMUX_GPIO76__FUNC_O_CMVREF7 (MTK_PIN_NO(76) | 5) +#define PINMUX_GPIO76__FUNC_O_GDU_SUM_TROOP2_1 (MTK_PIN_NO(76) | 6) +#define PINMUX_GPIO76__FUNC_B0_DBG_MON_A30 (MTK_PIN_NO(76) | 7) + +#define PINMUX_GPIO77__FUNC_B_GPIO77 (MTK_PIN_NO(77) | 0) +#define PINMUX_GPIO77__FUNC_B0_SPIM1_MOSI (MTK_PIN_NO(77) | 1) +#define PINMUX_GPIO77__FUNC_O_SCP_SPI1_A_MO (MTK_PIN_NO(77) | 2) +#define PINMUX_GPIO77__FUNC_B0_TDMIN_LRCK (MTK_PIN_NO(77) | 3) +#define PINMUX_GPIO77__FUNC_B1_SCP_SCL1 (MTK_PIN_NO(77) | 4) +#define PINMUX_GPIO77__FUNC_O_GDU_SUM_TROOP2_2 (MTK_PIN_NO(77) | 6) +#define PINMUX_GPIO77__FUNC_B0_DBG_MON_A31 (MTK_PIN_NO(77) | 7) + +#define PINMUX_GPIO78__FUNC_B_GPIO78 (MTK_PIN_NO(78) | 0) +#define PINMUX_GPIO78__FUNC_B0_SPIM1_MISO (MTK_PIN_NO(78) | 1) +#define PINMUX_GPIO78__FUNC_I0_SCP_SPI1_A_MI (MTK_PIN_NO(78) | 2) +#define PINMUX_GPIO78__FUNC_I0_TDMIN_DI (MTK_PIN_NO(78) | 3) +#define PINMUX_GPIO78__FUNC_B1_SCP_SDA1 (MTK_PIN_NO(78) | 4) +#define PINMUX_GPIO78__FUNC_B0_DBG_MON_A32 (MTK_PIN_NO(78) | 7) + +#define PINMUX_GPIO79__FUNC_B_GPIO79 (MTK_PIN_NO(79) | 0) +#define PINMUX_GPIO79__FUNC_O_SPIM2_CSB (MTK_PIN_NO(79) | 1) +#define PINMUX_GPIO79__FUNC_O_SCP_SPI2_CS (MTK_PIN_NO(79) | 2) +#define PINMUX_GPIO79__FUNC_O_I2SO1_MCK (MTK_PIN_NO(79) | 3) +#define PINMUX_GPIO79__FUNC_O_UTXD2 (MTK_PIN_NO(79) | 4) +#define PINMUX_GPIO79__FUNC_O_TP_UTXD2_AO (MTK_PIN_NO(79) | 5) +#define PINMUX_GPIO79__FUNC_B0_PCM_SYNC (MTK_PIN_NO(79) | 6) +#define PINMUX_GPIO79__FUNC_B0_DBG_MON_B0 (MTK_PIN_NO(79) | 7) + +#define PINMUX_GPIO80__FUNC_B_GPIO80 (MTK_PIN_NO(80) | 0) +#define PINMUX_GPIO80__FUNC_O_SPIM2_CLK (MTK_PIN_NO(80) | 1) +#define PINMUX_GPIO80__FUNC_O_SCP_SPI2_CK (MTK_PIN_NO(80) | 2) +#define PINMUX_GPIO80__FUNC_O_I2SO1_BCK (MTK_PIN_NO(80) | 3) +#define PINMUX_GPIO80__FUNC_I1_URXD2 (MTK_PIN_NO(80) | 4) +#define PINMUX_GPIO80__FUNC_I1_TP_URXD2_AO (MTK_PIN_NO(80) | 5) +#define PINMUX_GPIO80__FUNC_B0_PCM_CLK (MTK_PIN_NO(80) | 6) +#define PINMUX_GPIO80__FUNC_B0_DBG_MON_B1 (MTK_PIN_NO(80) | 7) + +#define PINMUX_GPIO81__FUNC_B_GPIO81 (MTK_PIN_NO(81) | 0) +#define PINMUX_GPIO81__FUNC_B0_SPIM2_MOSI (MTK_PIN_NO(81) | 1) +#define PINMUX_GPIO81__FUNC_O_SCP_SPI2_MO (MTK_PIN_NO(81) | 2) +#define PINMUX_GPIO81__FUNC_O_I2SO1_WS (MTK_PIN_NO(81) | 3) +#define PINMUX_GPIO81__FUNC_O_URTS2 (MTK_PIN_NO(81) | 4) +#define PINMUX_GPIO81__FUNC_O_TP_URTS2_AO (MTK_PIN_NO(81) | 5) +#define PINMUX_GPIO81__FUNC_O_PCM_DO (MTK_PIN_NO(81) | 6) +#define PINMUX_GPIO81__FUNC_B0_DBG_MON_B2 (MTK_PIN_NO(81) | 7) + +#define PINMUX_GPIO82__FUNC_B_GPIO82 (MTK_PIN_NO(82) | 0) +#define PINMUX_GPIO82__FUNC_B0_SPIM2_MISO (MTK_PIN_NO(82) | 1) +#define PINMUX_GPIO82__FUNC_I0_SCP_SPI2_MI (MTK_PIN_NO(82) | 2) +#define PINMUX_GPIO82__FUNC_O_I2SO1_D0 (MTK_PIN_NO(82) | 3) +#define PINMUX_GPIO82__FUNC_I1_UCTS2 (MTK_PIN_NO(82) | 4) +#define PINMUX_GPIO82__FUNC_I1_TP_UCTS2_AO (MTK_PIN_NO(82) | 5) +#define PINMUX_GPIO82__FUNC_I0_PCM_DI (MTK_PIN_NO(82) | 6) +#define PINMUX_GPIO82__FUNC_B0_DBG_MON_B3 (MTK_PIN_NO(82) | 7) + +#define PINMUX_GPIO83__FUNC_B_GPIO83 (MTK_PIN_NO(83) | 0) +#define PINMUX_GPIO83__FUNC_I1_IDDIG (MTK_PIN_NO(83) | 1) + +#define PINMUX_GPIO84__FUNC_B_GPIO84 (MTK_PIN_NO(84) | 0) +#define PINMUX_GPIO84__FUNC_O_USB_DRVVBUS (MTK_PIN_NO(84) | 1) + +#define PINMUX_GPIO85__FUNC_B_GPIO85 (MTK_PIN_NO(85) | 0) +#define PINMUX_GPIO85__FUNC_I0_VBUSVALID (MTK_PIN_NO(85) | 1) + +#define PINMUX_GPIO86__FUNC_B_GPIO86 (MTK_PIN_NO(86) | 0) +#define PINMUX_GPIO86__FUNC_I1_IDDIG_1P (MTK_PIN_NO(86) | 1) +#define PINMUX_GPIO86__FUNC_O_UTXD1 (MTK_PIN_NO(86) | 2) +#define PINMUX_GPIO86__FUNC_O_URTS2 (MTK_PIN_NO(86) | 3) +#define PINMUX_GPIO86__FUNC_O_PWM_2 (MTK_PIN_NO(86) | 4) +#define PINMUX_GPIO86__FUNC_B0_TP_GPIO4_AO (MTK_PIN_NO(86) | 5) +#define PINMUX_GPIO86__FUNC_O_AUXIF_ST0 (MTK_PIN_NO(86) | 6) +#define PINMUX_GPIO86__FUNC_B0_DBG_MON_B4 (MTK_PIN_NO(86) | 7) + +#define PINMUX_GPIO87__FUNC_B_GPIO87 (MTK_PIN_NO(87) | 0) +#define PINMUX_GPIO87__FUNC_O_USB_DRVVBUS_1P (MTK_PIN_NO(87) | 1) +#define PINMUX_GPIO87__FUNC_I1_URXD1 (MTK_PIN_NO(87) | 2) +#define PINMUX_GPIO87__FUNC_I1_UCTS2 (MTK_PIN_NO(87) | 3) +#define PINMUX_GPIO87__FUNC_O_PWM_3 (MTK_PIN_NO(87) | 4) +#define PINMUX_GPIO87__FUNC_B0_TP_GPIO5_AO (MTK_PIN_NO(87) | 5) +#define PINMUX_GPIO87__FUNC_O_AUXIF_CLK0 (MTK_PIN_NO(87) | 6) +#define PINMUX_GPIO87__FUNC_B0_DBG_MON_B5 (MTK_PIN_NO(87) | 7) + +#define PINMUX_GPIO88__FUNC_B_GPIO88 (MTK_PIN_NO(88) | 0) +#define PINMUX_GPIO88__FUNC_I0_VBUSVALID_1P (MTK_PIN_NO(88) | 1) +#define PINMUX_GPIO88__FUNC_O_UTXD2 (MTK_PIN_NO(88) | 2) +#define PINMUX_GPIO88__FUNC_O_URTS1 (MTK_PIN_NO(88) | 3) +#define PINMUX_GPIO88__FUNC_O_CLKM2 (MTK_PIN_NO(88) | 4) +#define PINMUX_GPIO88__FUNC_B0_TP_GPIO6_AO (MTK_PIN_NO(88) | 5) +#define PINMUX_GPIO88__FUNC_O_AUXIF_ST1 (MTK_PIN_NO(88) | 6) +#define PINMUX_GPIO88__FUNC_B0_DBG_MON_B6 (MTK_PIN_NO(88) | 7) + +#define PINMUX_GPIO89__FUNC_B_GPIO89 (MTK_PIN_NO(89) | 0) +#define PINMUX_GPIO89__FUNC_I1_IDDIG_2P (MTK_PIN_NO(89) | 1) +#define PINMUX_GPIO89__FUNC_I1_URXD2 (MTK_PIN_NO(89) | 2) +#define PINMUX_GPIO89__FUNC_I1_UCTS1 (MTK_PIN_NO(89) | 3) +#define PINMUX_GPIO89__FUNC_O_CLKM3 (MTK_PIN_NO(89) | 4) +#define PINMUX_GPIO89__FUNC_B0_TP_GPIO7_AO (MTK_PIN_NO(89) | 5) +#define PINMUX_GPIO89__FUNC_O_AUXIF_CLK1 (MTK_PIN_NO(89) | 6) +#define PINMUX_GPIO89__FUNC_B0_DBG_MON_B7 (MTK_PIN_NO(89) | 7) + +#define PINMUX_GPIO90__FUNC_B_GPIO90 (MTK_PIN_NO(90) | 0) +#define PINMUX_GPIO90__FUNC_O_USB_DRVVBUS_2P (MTK_PIN_NO(90) | 1) +#define PINMUX_GPIO90__FUNC_O_UTXD3 (MTK_PIN_NO(90) | 2) +#define PINMUX_GPIO90__FUNC_O_ADSP_UTXD0 (MTK_PIN_NO(90) | 3) +#define PINMUX_GPIO90__FUNC_O_SSPM_UTXD_AO (MTK_PIN_NO(90) | 4) +#define PINMUX_GPIO90__FUNC_O_MD32_0_TXD (MTK_PIN_NO(90) | 5) +#define PINMUX_GPIO90__FUNC_O_MD32_1_TXD (MTK_PIN_NO(90) | 6) +#define PINMUX_GPIO90__FUNC_B0_DBG_MON_B8 (MTK_PIN_NO(90) | 7) + +#define PINMUX_GPIO91__FUNC_B_GPIO91 (MTK_PIN_NO(91) | 0) +#define PINMUX_GPIO91__FUNC_I0_VBUSVALID_2P (MTK_PIN_NO(91) | 1) +#define PINMUX_GPIO91__FUNC_I1_URXD3 (MTK_PIN_NO(91) | 2) +#define PINMUX_GPIO91__FUNC_I1_ADSP_URXD0 (MTK_PIN_NO(91) | 3) +#define PINMUX_GPIO91__FUNC_I1_SSPM_URXD_AO (MTK_PIN_NO(91) | 4) +#define PINMUX_GPIO91__FUNC_I1_MD32_0_RXD (MTK_PIN_NO(91) | 5) +#define PINMUX_GPIO91__FUNC_I1_MD32_1_RXD (MTK_PIN_NO(91) | 6) +#define PINMUX_GPIO91__FUNC_B0_DBG_MON_B9 (MTK_PIN_NO(91) | 7) + +#define PINMUX_GPIO92__FUNC_B_GPIO92 (MTK_PIN_NO(92) | 0) +#define PINMUX_GPIO92__FUNC_O_PWRAP_SPI0_CSN (MTK_PIN_NO(92) | 1) + +#define PINMUX_GPIO93__FUNC_B_GPIO93 (MTK_PIN_NO(93) | 0) +#define PINMUX_GPIO93__FUNC_O_PWRAP_SPI0_CK (MTK_PIN_NO(93) | 1) + +#define PINMUX_GPIO94__FUNC_B_GPIO94 (MTK_PIN_NO(94) | 0) +#define PINMUX_GPIO94__FUNC_B0_PWRAP_SPI0_MO (MTK_PIN_NO(94) | 1) +#define PINMUX_GPIO94__FUNC_B0_PWRAP_SPI0_MI (MTK_PIN_NO(94) | 2) + +#define PINMUX_GPIO95__FUNC_B_GPIO95 (MTK_PIN_NO(95) | 0) +#define PINMUX_GPIO95__FUNC_B0_PWRAP_SPI0_MI (MTK_PIN_NO(95) | 1) +#define PINMUX_GPIO95__FUNC_B0_PWRAP_SPI0_MO (MTK_PIN_NO(95) | 2) + +#define PINMUX_GPIO96__FUNC_B_GPIO96 (MTK_PIN_NO(96) | 0) +#define PINMUX_GPIO96__FUNC_O_SRCLKENA0 (MTK_PIN_NO(96) | 1) + +#define PINMUX_GPIO97__FUNC_B_GPIO97 (MTK_PIN_NO(97) | 0) +#define PINMUX_GPIO97__FUNC_O_SRCLKENA1 (MTK_PIN_NO(97) | 1) + +#define PINMUX_GPIO98__FUNC_B_GPIO98 (MTK_PIN_NO(98) | 0) +#define PINMUX_GPIO98__FUNC_O_SCP_VREQ_VAO (MTK_PIN_NO(98) | 1) +#define PINMUX_GPIO98__FUNC_I0_DVFSRC_EXT_REQ (MTK_PIN_NO(98) | 2) + +#define PINMUX_GPIO99__FUNC_B_GPIO99 (MTK_PIN_NO(99) | 0) +#define PINMUX_GPIO99__FUNC_I0_RTC32K_CK (MTK_PIN_NO(99) | 1) + +#define PINMUX_GPIO100__FUNC_B_GPIO100 (MTK_PIN_NO(100) | 0) +#define PINMUX_GPIO100__FUNC_O_WATCHDOG (MTK_PIN_NO(100) | 1) + +#define PINMUX_GPIO101__FUNC_B_GPIO101 (MTK_PIN_NO(101) | 0) +#define PINMUX_GPIO101__FUNC_O_AUD_CLK_MOSI (MTK_PIN_NO(101) | 1) +#define PINMUX_GPIO101__FUNC_O_I2SO1_MCK (MTK_PIN_NO(101) | 2) +#define PINMUX_GPIO101__FUNC_B0_I2SIN_BCK (MTK_PIN_NO(101) | 3) + +#define PINMUX_GPIO102__FUNC_B_GPIO102 (MTK_PIN_NO(102) | 0) +#define PINMUX_GPIO102__FUNC_O_AUD_SYNC_MOSI (MTK_PIN_NO(102) | 1) +#define PINMUX_GPIO102__FUNC_O_I2SO1_BCK (MTK_PIN_NO(102) | 2) +#define PINMUX_GPIO102__FUNC_B0_I2SIN_WS (MTK_PIN_NO(102) | 3) + +#define PINMUX_GPIO103__FUNC_B_GPIO103 (MTK_PIN_NO(103) | 0) +#define PINMUX_GPIO103__FUNC_O_AUD_DAT_MOSI0 (MTK_PIN_NO(103) | 1) +#define PINMUX_GPIO103__FUNC_O_I2SO1_WS (MTK_PIN_NO(103) | 2) +#define PINMUX_GPIO103__FUNC_I0_I2SIN_D0 (MTK_PIN_NO(103) | 3) + +#define PINMUX_GPIO104__FUNC_B_GPIO104 (MTK_PIN_NO(104) | 0) +#define PINMUX_GPIO104__FUNC_O_AUD_DAT_MOSI1 (MTK_PIN_NO(104) | 1) +#define PINMUX_GPIO104__FUNC_O_I2SO1_D0 (MTK_PIN_NO(104) | 2) +#define PINMUX_GPIO104__FUNC_I0_I2SIN_D1 (MTK_PIN_NO(104) | 3) + +#define PINMUX_GPIO105__FUNC_B_GPIO105 (MTK_PIN_NO(105) | 0) +#define PINMUX_GPIO105__FUNC_I0_AUD_DAT_MISO0 (MTK_PIN_NO(105) | 1) +#define PINMUX_GPIO105__FUNC_I0_VOW_DAT_MISO (MTK_PIN_NO(105) | 2) +#define PINMUX_GPIO105__FUNC_I0_I2SIN_D2 (MTK_PIN_NO(105) | 3) + +#define PINMUX_GPIO106__FUNC_B_GPIO106 (MTK_PIN_NO(106) | 0) +#define PINMUX_GPIO106__FUNC_I0_AUD_DAT_MISO1 (MTK_PIN_NO(106) | 1) +#define PINMUX_GPIO106__FUNC_I0_VOW_CLK_MISO (MTK_PIN_NO(106) | 2) +#define PINMUX_GPIO106__FUNC_I0_I2SIN_D3 (MTK_PIN_NO(106) | 3) + +#define PINMUX_GPIO107__FUNC_B_GPIO107 (MTK_PIN_NO(107) | 0) +#define PINMUX_GPIO107__FUNC_B0_I2SIN_MCK (MTK_PIN_NO(107) | 1) +#define PINMUX_GPIO107__FUNC_I0_SPLIN_MCK (MTK_PIN_NO(107) | 2) +#define PINMUX_GPIO107__FUNC_I0_SPDIF_IN0 (MTK_PIN_NO(107) | 3) +#define PINMUX_GPIO107__FUNC_O_CMVREF4 (MTK_PIN_NO(107) | 4) +#define PINMUX_GPIO107__FUNC_O_AUXIF_ST0 (MTK_PIN_NO(107) | 5) +#define PINMUX_GPIO107__FUNC_O_PGD_LV_LSC_PWR0 (MTK_PIN_NO(107) | 6) + +#define PINMUX_GPIO108__FUNC_B_GPIO108 (MTK_PIN_NO(108) | 0) +#define PINMUX_GPIO108__FUNC_B0_I2SIN_BCK (MTK_PIN_NO(108) | 1) +#define PINMUX_GPIO108__FUNC_I0_SPLIN_LRCK (MTK_PIN_NO(108) | 2) +#define PINMUX_GPIO108__FUNC_O_DMIC4_CLK (MTK_PIN_NO(108) | 3) +#define PINMUX_GPIO108__FUNC_O_CMVREF5 (MTK_PIN_NO(108) | 4) +#define PINMUX_GPIO108__FUNC_O_AUXIF_CLK0 (MTK_PIN_NO(108) | 5) +#define PINMUX_GPIO108__FUNC_O_PGD_LV_LSC_PWR1 (MTK_PIN_NO(108) | 6) +#define PINMUX_GPIO108__FUNC_B0_DBG_MON_B10 (MTK_PIN_NO(108) | 7) + +#define PINMUX_GPIO109__FUNC_B_GPIO109 (MTK_PIN_NO(109) | 0) +#define PINMUX_GPIO109__FUNC_B0_I2SIN_WS (MTK_PIN_NO(109) | 1) +#define PINMUX_GPIO109__FUNC_I0_SPLIN_BCK (MTK_PIN_NO(109) | 2) +#define PINMUX_GPIO109__FUNC_I0_DMIC4_DAT (MTK_PIN_NO(109) | 3) +#define PINMUX_GPIO109__FUNC_O_CMVREF6 (MTK_PIN_NO(109) | 4) +#define PINMUX_GPIO109__FUNC_O_AUXIF_ST1 (MTK_PIN_NO(109) | 5) +#define PINMUX_GPIO109__FUNC_O_PGD_LV_LSC_PWR2 (MTK_PIN_NO(109) | 6) +#define PINMUX_GPIO109__FUNC_B0_DBG_MON_B11 (MTK_PIN_NO(109) | 7) + +#define PINMUX_GPIO110__FUNC_B_GPIO110 (MTK_PIN_NO(110) | 0) +#define PINMUX_GPIO110__FUNC_I0_I2SIN_D0 (MTK_PIN_NO(110) | 1) +#define PINMUX_GPIO110__FUNC_I0_SPLIN_D0 (MTK_PIN_NO(110) | 2) +#define PINMUX_GPIO110__FUNC_I0_DMIC4_DAT_R (MTK_PIN_NO(110) | 3) +#define PINMUX_GPIO110__FUNC_O_CMVREF7 (MTK_PIN_NO(110) | 4) +#define PINMUX_GPIO110__FUNC_O_AUXIF_CLK1 (MTK_PIN_NO(110) | 5) +#define PINMUX_GPIO110__FUNC_O_PGD_LV_LSC_PWR3 (MTK_PIN_NO(110) | 6) +#define PINMUX_GPIO110__FUNC_B0_DBG_MON_B12 (MTK_PIN_NO(110) | 7) + +#define PINMUX_GPIO111__FUNC_B_GPIO111 (MTK_PIN_NO(111) | 0) +#define PINMUX_GPIO111__FUNC_I0_I2SIN_D1 (MTK_PIN_NO(111) | 1) +#define PINMUX_GPIO111__FUNC_I0_SPLIN_D1 (MTK_PIN_NO(111) | 2) +#define PINMUX_GPIO111__FUNC_O_DMIC3_CLK (MTK_PIN_NO(111) | 3) +#define PINMUX_GPIO111__FUNC_O_SPDIF_OUT (MTK_PIN_NO(111) | 4) +#define PINMUX_GPIO111__FUNC_O_PGD_LV_LSC_PWR4 (MTK_PIN_NO(111) | 6) +#define PINMUX_GPIO111__FUNC_B0_DBG_MON_B13 (MTK_PIN_NO(111) | 7) + +#define PINMUX_GPIO112__FUNC_B_GPIO112 (MTK_PIN_NO(112) | 0) +#define PINMUX_GPIO112__FUNC_I0_I2SIN_D2 (MTK_PIN_NO(112) | 1) +#define PINMUX_GPIO112__FUNC_I0_SPLIN_D2 (MTK_PIN_NO(112) | 2) +#define PINMUX_GPIO112__FUNC_I0_DMIC3_DAT (MTK_PIN_NO(112) | 3) +#define PINMUX_GPIO112__FUNC_B0_TDMIN_MCK (MTK_PIN_NO(112) | 4) +#define PINMUX_GPIO112__FUNC_O_I2SO1_WS (MTK_PIN_NO(112) | 5) +#define PINMUX_GPIO112__FUNC_O_PGD_LV_LSC_PWR5 (MTK_PIN_NO(112) | 6) +#define PINMUX_GPIO112__FUNC_B0_DBG_MON_B14 (MTK_PIN_NO(112) | 7) + +#define PINMUX_GPIO113__FUNC_B_GPIO113 (MTK_PIN_NO(113) | 0) +#define PINMUX_GPIO113__FUNC_I0_I2SIN_D3 (MTK_PIN_NO(113) | 1) +#define PINMUX_GPIO113__FUNC_I0_SPLIN_D3 (MTK_PIN_NO(113) | 2) +#define PINMUX_GPIO113__FUNC_I0_DMIC3_DAT_R (MTK_PIN_NO(113) | 3) +#define PINMUX_GPIO113__FUNC_B0_TDMIN_BCK (MTK_PIN_NO(113) | 4) +#define PINMUX_GPIO113__FUNC_O_I2SO1_D0 (MTK_PIN_NO(113) | 5) +#define PINMUX_GPIO113__FUNC_B0_DBG_MON_B15 (MTK_PIN_NO(113) | 7) + +#define PINMUX_GPIO114__FUNC_B_GPIO114 (MTK_PIN_NO(114) | 0) +#define PINMUX_GPIO114__FUNC_O_I2SO2_MCK (MTK_PIN_NO(114) | 1) +#define PINMUX_GPIO114__FUNC_B0_I2SIN_MCK (MTK_PIN_NO(114) | 2) +#define PINMUX_GPIO114__FUNC_I1_MCUPM_JTAG_TMS (MTK_PIN_NO(114) | 3) +#define PINMUX_GPIO114__FUNC_B1_APU_JTAG_TMS (MTK_PIN_NO(114) | 4) +#define PINMUX_GPIO114__FUNC_I1_SCP_JTAG1_TMS (MTK_PIN_NO(114) | 5) +#define PINMUX_GPIO114__FUNC_I1_SPM_JTAG_TMS (MTK_PIN_NO(114) | 6) +#define PINMUX_GPIO114__FUNC_B0_DBG_MON_B16 (MTK_PIN_NO(114) | 7) + +#define PINMUX_GPIO115__FUNC_B_GPIO115 (MTK_PIN_NO(115) | 0) +#define PINMUX_GPIO115__FUNC_B0_I2SO2_BCK (MTK_PIN_NO(115) | 1) +#define PINMUX_GPIO115__FUNC_B0_I2SIN_BCK (MTK_PIN_NO(115) | 2) +#define PINMUX_GPIO115__FUNC_I1_MCUPM_JTAG_TCK (MTK_PIN_NO(115) | 3) +#define PINMUX_GPIO115__FUNC_I0_APU_JTAG_TCK (MTK_PIN_NO(115) | 4) +#define PINMUX_GPIO115__FUNC_I1_SCP_JTAG1_TCK (MTK_PIN_NO(115) | 5) +#define PINMUX_GPIO115__FUNC_I1_SPM_JTAG_TCK (MTK_PIN_NO(115) | 6) +#define PINMUX_GPIO115__FUNC_B0_DBG_MON_B17 (MTK_PIN_NO(115) | 7) + +#define PINMUX_GPIO116__FUNC_B_GPIO116 (MTK_PIN_NO(116) | 0) +#define PINMUX_GPIO116__FUNC_B0_I2SO2_WS (MTK_PIN_NO(116) | 1) +#define PINMUX_GPIO116__FUNC_B0_I2SIN_WS (MTK_PIN_NO(116) | 2) +#define PINMUX_GPIO116__FUNC_I1_MCUPM_JTAG_TDI (MTK_PIN_NO(116) | 3) +#define PINMUX_GPIO116__FUNC_I1_APU_JTAG_TDI (MTK_PIN_NO(116) | 4) +#define PINMUX_GPIO116__FUNC_I1_SCP_JTAG1_TDI (MTK_PIN_NO(116) | 5) +#define PINMUX_GPIO116__FUNC_I1_SPM_JTAG_TDI (MTK_PIN_NO(116) | 6) +#define PINMUX_GPIO116__FUNC_B0_DBG_MON_B18 (MTK_PIN_NO(116) | 7) + +#define PINMUX_GPIO117__FUNC_B_GPIO117 (MTK_PIN_NO(117) | 0) +#define PINMUX_GPIO117__FUNC_O_I2SO2_D0 (MTK_PIN_NO(117) | 1) +#define PINMUX_GPIO117__FUNC_I0_I2SIN_D0 (MTK_PIN_NO(117) | 2) +#define PINMUX_GPIO117__FUNC_O_MCUPM_JTAG_TDO (MTK_PIN_NO(117) | 3) +#define PINMUX_GPIO117__FUNC_O_APU_JTAG_TDO (MTK_PIN_NO(117) | 4) +#define PINMUX_GPIO117__FUNC_O_SCP_JTAG1_TDO (MTK_PIN_NO(117) | 5) +#define PINMUX_GPIO117__FUNC_O_SPM_JTAG_TDO (MTK_PIN_NO(117) | 6) +#define PINMUX_GPIO117__FUNC_B0_DBG_MON_B19 (MTK_PIN_NO(117) | 7) + +#define PINMUX_GPIO118__FUNC_B_GPIO118 (MTK_PIN_NO(118) | 0) +#define PINMUX_GPIO118__FUNC_O_I2SO2_D1 (MTK_PIN_NO(118) | 1) +#define PINMUX_GPIO118__FUNC_I0_I2SIN_D1 (MTK_PIN_NO(118) | 2) +#define PINMUX_GPIO118__FUNC_I0_MCUPM_JTAG_TRSTN (MTK_PIN_NO(118) | 3) +#define PINMUX_GPIO118__FUNC_I0_APU_JTAG_TRST (MTK_PIN_NO(118) | 4) +#define PINMUX_GPIO118__FUNC_I0_SCP_JTAG1_TRSTN (MTK_PIN_NO(118) | 5) +#define PINMUX_GPIO118__FUNC_I0_SPM_JTAG_TRSTN (MTK_PIN_NO(118) | 6) +#define PINMUX_GPIO118__FUNC_B0_DBG_MON_B20 (MTK_PIN_NO(118) | 7) + +#define PINMUX_GPIO119__FUNC_B_GPIO119 (MTK_PIN_NO(119) | 0) +#define PINMUX_GPIO119__FUNC_O_I2SO2_D2 (MTK_PIN_NO(119) | 1) +#define PINMUX_GPIO119__FUNC_I0_I2SIN_D2 (MTK_PIN_NO(119) | 2) +#define PINMUX_GPIO119__FUNC_O_UTXD3 (MTK_PIN_NO(119) | 3) +#define PINMUX_GPIO119__FUNC_B0_TDMIN_LRCK (MTK_PIN_NO(119) | 4) +#define PINMUX_GPIO119__FUNC_O_I2SO1_MCK (MTK_PIN_NO(119) | 5) +#define PINMUX_GPIO119__FUNC_O_SSPM_UTXD_AO (MTK_PIN_NO(119) | 6) +#define PINMUX_GPIO119__FUNC_B0_DBG_MON_B21 (MTK_PIN_NO(119) | 7) + +#define PINMUX_GPIO120__FUNC_B_GPIO120 (MTK_PIN_NO(120) | 0) +#define PINMUX_GPIO120__FUNC_O_I2SO2_D3 (MTK_PIN_NO(120) | 1) +#define PINMUX_GPIO120__FUNC_I0_I2SIN_D3 (MTK_PIN_NO(120) | 2) +#define PINMUX_GPIO120__FUNC_I1_URXD3 (MTK_PIN_NO(120) | 3) +#define PINMUX_GPIO120__FUNC_I0_TDMIN_DI (MTK_PIN_NO(120) | 4) +#define PINMUX_GPIO120__FUNC_O_I2SO1_BCK (MTK_PIN_NO(120) | 5) +#define PINMUX_GPIO120__FUNC_I1_SSPM_URXD_AO (MTK_PIN_NO(120) | 6) +#define PINMUX_GPIO120__FUNC_B0_DBG_MON_B22 (MTK_PIN_NO(120) | 7) + +#define PINMUX_GPIO121__FUNC_B_GPIO121 (MTK_PIN_NO(121) | 0) +#define PINMUX_GPIO121__FUNC_B0_PCM_CLK (MTK_PIN_NO(121) | 1) +#define PINMUX_GPIO121__FUNC_O_SPIM4_CSB (MTK_PIN_NO(121) | 2) +#define PINMUX_GPIO121__FUNC_O_SCP_SPI1_B_CS (MTK_PIN_NO(121) | 3) +#define PINMUX_GPIO121__FUNC_O_TP_UTXD2_AO (MTK_PIN_NO(121) | 4) +#define PINMUX_GPIO121__FUNC_O_AUXIF_ST0 (MTK_PIN_NO(121) | 5) +#define PINMUX_GPIO121__FUNC_O_PGD_DA_EFUSE_RDY (MTK_PIN_NO(121) | 6) +#define PINMUX_GPIO121__FUNC_B0_DBG_MON_B23 (MTK_PIN_NO(121) | 7) + +#define PINMUX_GPIO122__FUNC_B_GPIO122 (MTK_PIN_NO(122) | 0) +#define PINMUX_GPIO122__FUNC_B0_PCM_SYNC (MTK_PIN_NO(122) | 1) +#define PINMUX_GPIO122__FUNC_O_SPIM4_CLK (MTK_PIN_NO(122) | 2) +#define PINMUX_GPIO122__FUNC_O_SCP_SPI1_B_CK (MTK_PIN_NO(122) | 3) +#define PINMUX_GPIO122__FUNC_I1_TP_URXD2_AO (MTK_PIN_NO(122) | 4) +#define PINMUX_GPIO122__FUNC_O_AUXIF_CLK0 (MTK_PIN_NO(122) | 5) +#define PINMUX_GPIO122__FUNC_O_PGD_DA_EFUSE_RDY_PRE (MTK_PIN_NO(122) | 6) +#define PINMUX_GPIO122__FUNC_B0_DBG_MON_B24 (MTK_PIN_NO(122) | 7) + +#define PINMUX_GPIO123__FUNC_B_GPIO123 (MTK_PIN_NO(123) | 0) +#define PINMUX_GPIO123__FUNC_O_PCM_DO (MTK_PIN_NO(123) | 1) +#define PINMUX_GPIO123__FUNC_B0_SPIM4_MOSI (MTK_PIN_NO(123) | 2) +#define PINMUX_GPIO123__FUNC_O_SCP_SPI1_B_MO (MTK_PIN_NO(123) | 3) +#define PINMUX_GPIO123__FUNC_O_TP_URTS2_AO (MTK_PIN_NO(123) | 4) +#define PINMUX_GPIO123__FUNC_O_AUXIF_ST1 (MTK_PIN_NO(123) | 5) +#define PINMUX_GPIO123__FUNC_O_PGD_DA_PWRGD_RESET (MTK_PIN_NO(123) | 6) +#define PINMUX_GPIO123__FUNC_B0_DBG_MON_B25 (MTK_PIN_NO(123) | 7) + +#define PINMUX_GPIO124__FUNC_B_GPIO124 (MTK_PIN_NO(124) | 0) +#define PINMUX_GPIO124__FUNC_I0_PCM_DI (MTK_PIN_NO(124) | 1) +#define PINMUX_GPIO124__FUNC_B0_SPIM4_MISO (MTK_PIN_NO(124) | 2) +#define PINMUX_GPIO124__FUNC_I0_SCP_SPI1_B_MI (MTK_PIN_NO(124) | 3) +#define PINMUX_GPIO124__FUNC_I1_TP_UCTS2_AO (MTK_PIN_NO(124) | 4) +#define PINMUX_GPIO124__FUNC_O_AUXIF_CLK1 (MTK_PIN_NO(124) | 5) +#define PINMUX_GPIO124__FUNC_O_PGD_DA_PWRGD_ENB (MTK_PIN_NO(124) | 6) +#define PINMUX_GPIO124__FUNC_B0_DBG_MON_B26 (MTK_PIN_NO(124) | 7) + +#define PINMUX_GPIO125__FUNC_B_GPIO125 (MTK_PIN_NO(125) | 0) +#define PINMUX_GPIO125__FUNC_O_DMIC1_CLK (MTK_PIN_NO(125) | 1) +#define PINMUX_GPIO125__FUNC_O_SPINOR_CK (MTK_PIN_NO(125) | 2) +#define PINMUX_GPIO125__FUNC_B0_TDMIN_MCK (MTK_PIN_NO(125) | 3) +#define PINMUX_GPIO125__FUNC_O_LVTS_FOUT (MTK_PIN_NO(125) | 6) +#define PINMUX_GPIO125__FUNC_B0_DBG_MON_B27 (MTK_PIN_NO(125) | 7) + +#define PINMUX_GPIO126__FUNC_B_GPIO126 (MTK_PIN_NO(126) | 0) +#define PINMUX_GPIO126__FUNC_I0_DMIC1_DAT (MTK_PIN_NO(126) | 1) +#define PINMUX_GPIO126__FUNC_O_SPINOR_CS (MTK_PIN_NO(126) | 2) +#define PINMUX_GPIO126__FUNC_B0_TDMIN_BCK (MTK_PIN_NO(126) | 3) +#define PINMUX_GPIO126__FUNC_O_LVTS_SDO (MTK_PIN_NO(126) | 6) +#define PINMUX_GPIO126__FUNC_B0_DBG_MON_B28 (MTK_PIN_NO(126) | 7) + +#define PINMUX_GPIO127__FUNC_B_GPIO127 (MTK_PIN_NO(127) | 0) +#define PINMUX_GPIO127__FUNC_I0_DMIC1_DAT_R (MTK_PIN_NO(127) | 1) +#define PINMUX_GPIO127__FUNC_B0_SPINOR_IO0 (MTK_PIN_NO(127) | 2) +#define PINMUX_GPIO127__FUNC_B0_TDMIN_LRCK (MTK_PIN_NO(127) | 3) +#define PINMUX_GPIO127__FUNC_I0_LVTS_26M (MTK_PIN_NO(127) | 6) +#define PINMUX_GPIO127__FUNC_B0_DBG_MON_B29 (MTK_PIN_NO(127) | 7) + +#define PINMUX_GPIO128__FUNC_B_GPIO128 (MTK_PIN_NO(128) | 0) +#define PINMUX_GPIO128__FUNC_O_DMIC2_CLK (MTK_PIN_NO(128) | 1) +#define PINMUX_GPIO128__FUNC_B0_SPINOR_IO1 (MTK_PIN_NO(128) | 2) +#define PINMUX_GPIO128__FUNC_I0_TDMIN_DI (MTK_PIN_NO(128) | 3) +#define PINMUX_GPIO128__FUNC_I0_LVTS_SCF (MTK_PIN_NO(128) | 6) +#define PINMUX_GPIO128__FUNC_B0_DBG_MON_B30 (MTK_PIN_NO(128) | 7) + +#define PINMUX_GPIO129__FUNC_B_GPIO129 (MTK_PIN_NO(129) | 0) +#define PINMUX_GPIO129__FUNC_I0_DMIC2_DAT (MTK_PIN_NO(129) | 1) +#define PINMUX_GPIO129__FUNC_B0_SPINOR_IO2 (MTK_PIN_NO(129) | 2) +#define PINMUX_GPIO129__FUNC_I0_SPDIF_IN1 (MTK_PIN_NO(129) | 3) +#define PINMUX_GPIO129__FUNC_I0_LVTS_SCK (MTK_PIN_NO(129) | 6) +#define PINMUX_GPIO129__FUNC_B0_DBG_MON_B31 (MTK_PIN_NO(129) | 7) + +#define PINMUX_GPIO130__FUNC_B_GPIO130 (MTK_PIN_NO(130) | 0) +#define PINMUX_GPIO130__FUNC_I0_DMIC2_DAT_R (MTK_PIN_NO(130) | 1) +#define PINMUX_GPIO130__FUNC_B0_SPINOR_IO3 (MTK_PIN_NO(130) | 2) +#define PINMUX_GPIO130__FUNC_I0_SPDIF_IN2 (MTK_PIN_NO(130) | 3) +#define PINMUX_GPIO130__FUNC_I0_LVTS_SDI (MTK_PIN_NO(130) | 6) +#define PINMUX_GPIO130__FUNC_B0_DBG_MON_B32 (MTK_PIN_NO(130) | 7) + +#define PINMUX_GPIO131__FUNC_B_GPIO131 (MTK_PIN_NO(131) | 0) +#define PINMUX_GPIO131__FUNC_O_DPI_D0 (MTK_PIN_NO(131) | 1) +#define PINMUX_GPIO131__FUNC_O_GBE_TXD3 (MTK_PIN_NO(131) | 2) +#define PINMUX_GPIO131__FUNC_O_DMIC1_CLK (MTK_PIN_NO(131) | 3) +#define PINMUX_GPIO131__FUNC_O_I2SO2_MCK (MTK_PIN_NO(131) | 4) +#define PINMUX_GPIO131__FUNC_B0_TP_GPIO0_AO (MTK_PIN_NO(131) | 5) +#define PINMUX_GPIO131__FUNC_O_SPIM5_CSB (MTK_PIN_NO(131) | 6) +#define PINMUX_GPIO131__FUNC_O_PGD_LV_HSC_PWR0 (MTK_PIN_NO(131) | 7) + +#define PINMUX_GPIO132__FUNC_B_GPIO132 (MTK_PIN_NO(132) | 0) +#define PINMUX_GPIO132__FUNC_O_DPI_D1 (MTK_PIN_NO(132) | 1) +#define PINMUX_GPIO132__FUNC_O_GBE_TXD2 (MTK_PIN_NO(132) | 2) +#define PINMUX_GPIO132__FUNC_I0_DMIC1_DAT (MTK_PIN_NO(132) | 3) +#define PINMUX_GPIO132__FUNC_B0_I2SO2_BCK (MTK_PIN_NO(132) | 4) +#define PINMUX_GPIO132__FUNC_B0_TP_GPIO1_AO (MTK_PIN_NO(132) | 5) +#define PINMUX_GPIO132__FUNC_O_SPIM5_CLK (MTK_PIN_NO(132) | 6) +#define PINMUX_GPIO132__FUNC_O_PGD_LV_HSC_PWR1 (MTK_PIN_NO(132) | 7) + +#define PINMUX_GPIO133__FUNC_B_GPIO133 (MTK_PIN_NO(133) | 0) +#define PINMUX_GPIO133__FUNC_O_DPI_D2 (MTK_PIN_NO(133) | 1) +#define PINMUX_GPIO133__FUNC_O_GBE_TXD1 (MTK_PIN_NO(133) | 2) +#define PINMUX_GPIO133__FUNC_I0_DMIC1_DAT_R (MTK_PIN_NO(133) | 3) +#define PINMUX_GPIO133__FUNC_B0_I2SO2_WS (MTK_PIN_NO(133) | 4) +#define PINMUX_GPIO133__FUNC_B0_TP_GPIO2_AO (MTK_PIN_NO(133) | 5) +#define PINMUX_GPIO133__FUNC_B0_SPIM5_MOSI (MTK_PIN_NO(133) | 6) +#define PINMUX_GPIO133__FUNC_O_PGD_LV_HSC_PWR2 (MTK_PIN_NO(133) | 7) + +#define PINMUX_GPIO134__FUNC_B_GPIO134 (MTK_PIN_NO(134) | 0) +#define PINMUX_GPIO134__FUNC_O_DPI_D3 (MTK_PIN_NO(134) | 1) +#define PINMUX_GPIO134__FUNC_O_GBE_TXD0 (MTK_PIN_NO(134) | 2) +#define PINMUX_GPIO134__FUNC_O_DMIC2_CLK (MTK_PIN_NO(134) | 3) +#define PINMUX_GPIO134__FUNC_O_I2SO2_D0 (MTK_PIN_NO(134) | 4) +#define PINMUX_GPIO134__FUNC_B0_TP_GPIO3_AO (MTK_PIN_NO(134) | 5) +#define PINMUX_GPIO134__FUNC_B0_SPIM5_MISO (MTK_PIN_NO(134) | 6) +#define PINMUX_GPIO134__FUNC_O_PGD_LV_HSC_PWR3 (MTK_PIN_NO(134) | 7) + +#define PINMUX_GPIO135__FUNC_B_GPIO135 (MTK_PIN_NO(135) | 0) +#define PINMUX_GPIO135__FUNC_O_DPI_D4 (MTK_PIN_NO(135) | 1) +#define PINMUX_GPIO135__FUNC_I0_GBE_RXD3 (MTK_PIN_NO(135) | 2) +#define PINMUX_GPIO135__FUNC_I0_DMIC2_DAT (MTK_PIN_NO(135) | 3) +#define PINMUX_GPIO135__FUNC_O_I2SO2_D1 (MTK_PIN_NO(135) | 4) +#define PINMUX_GPIO135__FUNC_B0_TP_GPIO4_AO (MTK_PIN_NO(135) | 5) +#define PINMUX_GPIO135__FUNC_I1_WAKEN (MTK_PIN_NO(135) | 6) +#define PINMUX_GPIO135__FUNC_O_PGD_LV_HSC_PWR4 (MTK_PIN_NO(135) | 7) + +#define PINMUX_GPIO136__FUNC_B_GPIO136 (MTK_PIN_NO(136) | 0) +#define PINMUX_GPIO136__FUNC_O_DPI_D5 (MTK_PIN_NO(136) | 1) +#define PINMUX_GPIO136__FUNC_I0_GBE_RXD2 (MTK_PIN_NO(136) | 2) +#define PINMUX_GPIO136__FUNC_I0_DMIC2_DAT_R (MTK_PIN_NO(136) | 3) +#define PINMUX_GPIO136__FUNC_O_I2SO2_D2 (MTK_PIN_NO(136) | 4) +#define PINMUX_GPIO136__FUNC_B0_TP_GPIO5_AO (MTK_PIN_NO(136) | 5) +#define PINMUX_GPIO136__FUNC_O_PERSTN (MTK_PIN_NO(136) | 6) +#define PINMUX_GPIO136__FUNC_O_PGD_LV_HSC_PWR5 (MTK_PIN_NO(136) | 7) + +#define PINMUX_GPIO137__FUNC_B_GPIO137 (MTK_PIN_NO(137) | 0) +#define PINMUX_GPIO137__FUNC_O_DPI_D6 (MTK_PIN_NO(137) | 1) +#define PINMUX_GPIO137__FUNC_I0_GBE_RXD1 (MTK_PIN_NO(137) | 2) +#define PINMUX_GPIO137__FUNC_O_DMIC3_CLK (MTK_PIN_NO(137) | 3) +#define PINMUX_GPIO137__FUNC_O_I2SO2_D3 (MTK_PIN_NO(137) | 4) +#define PINMUX_GPIO137__FUNC_B0_TP_GPIO6_AO (MTK_PIN_NO(137) | 5) +#define PINMUX_GPIO137__FUNC_B1_CLKREQN (MTK_PIN_NO(137) | 6) +#define PINMUX_GPIO137__FUNC_O_PWM_0 (MTK_PIN_NO(137) | 7) + +#define PINMUX_GPIO138__FUNC_B_GPIO138 (MTK_PIN_NO(138) | 0) +#define PINMUX_GPIO138__FUNC_O_DPI_D7 (MTK_PIN_NO(138) | 1) +#define PINMUX_GPIO138__FUNC_I0_GBE_RXD0 (MTK_PIN_NO(138) | 2) +#define PINMUX_GPIO138__FUNC_I0_DMIC3_DAT (MTK_PIN_NO(138) | 3) +#define PINMUX_GPIO138__FUNC_O_CLKM2 (MTK_PIN_NO(138) | 4) +#define PINMUX_GPIO138__FUNC_B0_TP_GPIO7_AO (MTK_PIN_NO(138) | 5) +#define PINMUX_GPIO138__FUNC_B0_MD32_0_GPIO0 (MTK_PIN_NO(138) | 7) + +#define PINMUX_GPIO139__FUNC_B_GPIO139 (MTK_PIN_NO(139) | 0) +#define PINMUX_GPIO139__FUNC_O_DPI_D8 (MTK_PIN_NO(139) | 1) +#define PINMUX_GPIO139__FUNC_B0_GBE_TXC (MTK_PIN_NO(139) | 2) +#define PINMUX_GPIO139__FUNC_I0_DMIC3_DAT_R (MTK_PIN_NO(139) | 3) +#define PINMUX_GPIO139__FUNC_O_CLKM3 (MTK_PIN_NO(139) | 4) +#define PINMUX_GPIO139__FUNC_O_TP_UTXD2_AO (MTK_PIN_NO(139) | 5) +#define PINMUX_GPIO139__FUNC_O_UTXD2 (MTK_PIN_NO(139) | 6) +#define PINMUX_GPIO139__FUNC_B0_MD32_0_GPIO1 (MTK_PIN_NO(139) | 7) + +#define PINMUX_GPIO140__FUNC_B_GPIO140 (MTK_PIN_NO(140) | 0) +#define PINMUX_GPIO140__FUNC_O_DPI_D9 (MTK_PIN_NO(140) | 1) +#define PINMUX_GPIO140__FUNC_I0_GBE_RXC (MTK_PIN_NO(140) | 2) +#define PINMUX_GPIO140__FUNC_O_DMIC4_CLK (MTK_PIN_NO(140) | 3) +#define PINMUX_GPIO140__FUNC_O_PWM_2 (MTK_PIN_NO(140) | 4) +#define PINMUX_GPIO140__FUNC_I1_TP_URXD2_AO (MTK_PIN_NO(140) | 5) +#define PINMUX_GPIO140__FUNC_I1_URXD2 (MTK_PIN_NO(140) | 6) +#define PINMUX_GPIO140__FUNC_B0_MD32_0_GPIO2 (MTK_PIN_NO(140) | 7) + +#define PINMUX_GPIO141__FUNC_B_GPIO141 (MTK_PIN_NO(141) | 0) +#define PINMUX_GPIO141__FUNC_O_DPI_D10 (MTK_PIN_NO(141) | 1) +#define PINMUX_GPIO141__FUNC_I0_GBE_RXDV (MTK_PIN_NO(141) | 2) +#define PINMUX_GPIO141__FUNC_I0_DMIC4_DAT (MTK_PIN_NO(141) | 3) +#define PINMUX_GPIO141__FUNC_O_PWM_3 (MTK_PIN_NO(141) | 4) +#define PINMUX_GPIO141__FUNC_O_TP_URTS2_AO (MTK_PIN_NO(141) | 5) +#define PINMUX_GPIO141__FUNC_O_URTS2 (MTK_PIN_NO(141) | 6) +#define PINMUX_GPIO141__FUNC_B0_MD32_1_GPIO0 (MTK_PIN_NO(141) | 7) + +#define PINMUX_GPIO142__FUNC_B_GPIO142 (MTK_PIN_NO(142) | 0) +#define PINMUX_GPIO142__FUNC_O_DPI_D11 (MTK_PIN_NO(142) | 1) +#define PINMUX_GPIO142__FUNC_O_GBE_TXEN (MTK_PIN_NO(142) | 2) +#define PINMUX_GPIO142__FUNC_I0_DMIC4_DAT_R (MTK_PIN_NO(142) | 3) +#define PINMUX_GPIO142__FUNC_O_PWM_1 (MTK_PIN_NO(142) | 4) +#define PINMUX_GPIO142__FUNC_I1_TP_UCTS2_AO (MTK_PIN_NO(142) | 5) +#define PINMUX_GPIO142__FUNC_I1_UCTS2 (MTK_PIN_NO(142) | 6) +#define PINMUX_GPIO142__FUNC_B0_MD32_1_GPIO1 (MTK_PIN_NO(142) | 7) + +#define PINMUX_GPIO143__FUNC_B_GPIO143 (MTK_PIN_NO(143) | 0) +#define PINMUX_GPIO143__FUNC_O_DPI_D12 (MTK_PIN_NO(143) | 1) +#define PINMUX_GPIO143__FUNC_O_GBE_MDC (MTK_PIN_NO(143) | 2) +#define PINMUX_GPIO143__FUNC_B0_MD32_0_GPIO0 (MTK_PIN_NO(143) | 3) +#define PINMUX_GPIO143__FUNC_O_CLKM0 (MTK_PIN_NO(143) | 4) +#define PINMUX_GPIO143__FUNC_O_SPIM3_CSB (MTK_PIN_NO(143) | 5) +#define PINMUX_GPIO143__FUNC_O_UTXD1 (MTK_PIN_NO(143) | 6) +#define PINMUX_GPIO143__FUNC_B0_MD32_1_GPIO2 (MTK_PIN_NO(143) | 7) + +#define PINMUX_GPIO144__FUNC_B_GPIO144 (MTK_PIN_NO(144) | 0) +#define PINMUX_GPIO144__FUNC_O_DPI_D13 (MTK_PIN_NO(144) | 1) +#define PINMUX_GPIO144__FUNC_B1_GBE_MDIO (MTK_PIN_NO(144) | 2) +#define PINMUX_GPIO144__FUNC_B0_MD32_0_GPIO1 (MTK_PIN_NO(144) | 3) +#define PINMUX_GPIO144__FUNC_O_CLKM1 (MTK_PIN_NO(144) | 4) +#define PINMUX_GPIO144__FUNC_O_SPIM3_CLK (MTK_PIN_NO(144) | 5) +#define PINMUX_GPIO144__FUNC_I1_URXD1 (MTK_PIN_NO(144) | 6) +#define PINMUX_GPIO144__FUNC_O_PGD_HV_HSC_PWR0 (MTK_PIN_NO(144) | 7) + +#define PINMUX_GPIO145__FUNC_B_GPIO145 (MTK_PIN_NO(145) | 0) +#define PINMUX_GPIO145__FUNC_O_DPI_D14 (MTK_PIN_NO(145) | 1) +#define PINMUX_GPIO145__FUNC_O_GBE_TXER (MTK_PIN_NO(145) | 2) +#define PINMUX_GPIO145__FUNC_B0_MD32_1_GPIO0 (MTK_PIN_NO(145) | 3) +#define PINMUX_GPIO145__FUNC_O_CMFLASH0 (MTK_PIN_NO(145) | 4) +#define PINMUX_GPIO145__FUNC_B0_SPIM3_MOSI (MTK_PIN_NO(145) | 5) +#define PINMUX_GPIO145__FUNC_B0_GBE_AUX_PPS2 (MTK_PIN_NO(145) | 6) +#define PINMUX_GPIO145__FUNC_O_PGD_HV_HSC_PWR1 (MTK_PIN_NO(145) | 7) + +#define PINMUX_GPIO146__FUNC_B_GPIO146 (MTK_PIN_NO(146) | 0) +#define PINMUX_GPIO146__FUNC_O_DPI_D15 (MTK_PIN_NO(146) | 1) +#define PINMUX_GPIO146__FUNC_I0_GBE_RXER (MTK_PIN_NO(146) | 2) +#define PINMUX_GPIO146__FUNC_B0_MD32_1_GPIO1 (MTK_PIN_NO(146) | 3) +#define PINMUX_GPIO146__FUNC_O_CMFLASH1 (MTK_PIN_NO(146) | 4) +#define PINMUX_GPIO146__FUNC_B0_SPIM3_MISO (MTK_PIN_NO(146) | 5) +#define PINMUX_GPIO146__FUNC_B0_GBE_AUX_PPS3 (MTK_PIN_NO(146) | 6) +#define PINMUX_GPIO146__FUNC_O_PGD_HV_HSC_PWR2 (MTK_PIN_NO(146) | 7) + +#define PINMUX_GPIO147__FUNC_B_GPIO147 (MTK_PIN_NO(147) | 0) +#define PINMUX_GPIO147__FUNC_O_DPI_HSYNC (MTK_PIN_NO(147) | 1) +#define PINMUX_GPIO147__FUNC_I0_GBE_COL (MTK_PIN_NO(147) | 2) +#define PINMUX_GPIO147__FUNC_O_I2SO1_MCK (MTK_PIN_NO(147) | 3) +#define PINMUX_GPIO147__FUNC_O_CMVREF0 (MTK_PIN_NO(147) | 4) +#define PINMUX_GPIO147__FUNC_O_SPDIF_OUT (MTK_PIN_NO(147) | 5) +#define PINMUX_GPIO147__FUNC_O_URTS1 (MTK_PIN_NO(147) | 6) +#define PINMUX_GPIO147__FUNC_O_PGD_HV_HSC_PWR3 (MTK_PIN_NO(147) | 7) + +#define PINMUX_GPIO148__FUNC_B_GPIO148 (MTK_PIN_NO(148) | 0) +#define PINMUX_GPIO148__FUNC_O_DPI_VSYNC (MTK_PIN_NO(148) | 1) +#define PINMUX_GPIO148__FUNC_I0_GBE_INTR (MTK_PIN_NO(148) | 2) +#define PINMUX_GPIO148__FUNC_O_I2SO1_BCK (MTK_PIN_NO(148) | 3) +#define PINMUX_GPIO148__FUNC_O_CMVREF1 (MTK_PIN_NO(148) | 4) +#define PINMUX_GPIO148__FUNC_I0_SPDIF_IN0 (MTK_PIN_NO(148) | 5) +#define PINMUX_GPIO148__FUNC_I1_UCTS1 (MTK_PIN_NO(148) | 6) +#define PINMUX_GPIO148__FUNC_O_PGD_HV_HSC_PWR4 (MTK_PIN_NO(148) | 7) + +#define PINMUX_GPIO149__FUNC_B_GPIO149 (MTK_PIN_NO(149) | 0) +#define PINMUX_GPIO149__FUNC_O_DPI_DE (MTK_PIN_NO(149) | 1) +#define PINMUX_GPIO149__FUNC_B0_GBE_AUX_PPS0 (MTK_PIN_NO(149) | 2) +#define PINMUX_GPIO149__FUNC_O_I2SO1_WS (MTK_PIN_NO(149) | 3) +#define PINMUX_GPIO149__FUNC_O_CMVREF2 (MTK_PIN_NO(149) | 4) +#define PINMUX_GPIO149__FUNC_I0_SPDIF_IN1 (MTK_PIN_NO(149) | 5) +#define PINMUX_GPIO149__FUNC_O_UTXD3 (MTK_PIN_NO(149) | 6) +#define PINMUX_GPIO149__FUNC_O_PGD_HV_HSC_PWR5 (MTK_PIN_NO(149) | 7) + +#define PINMUX_GPIO150__FUNC_B_GPIO150 (MTK_PIN_NO(150) | 0) +#define PINMUX_GPIO150__FUNC_O_DPI_CK (MTK_PIN_NO(150) | 1) +#define PINMUX_GPIO150__FUNC_B0_GBE_AUX_PPS1 (MTK_PIN_NO(150) | 2) +#define PINMUX_GPIO150__FUNC_O_I2SO1_D0 (MTK_PIN_NO(150) | 3) +#define PINMUX_GPIO150__FUNC_O_CMVREF3 (MTK_PIN_NO(150) | 4) +#define PINMUX_GPIO150__FUNC_I0_SPDIF_IN2 (MTK_PIN_NO(150) | 5) +#define PINMUX_GPIO150__FUNC_I1_URXD3 (MTK_PIN_NO(150) | 6) + +#define PINMUX_GPIO151__FUNC_B_GPIO151 (MTK_PIN_NO(151) | 0) +#define PINMUX_GPIO151__FUNC_B1_MSDC0_DAT7 (MTK_PIN_NO(151) | 1) + +#define PINMUX_GPIO152__FUNC_B_GPIO152 (MTK_PIN_NO(152) | 0) +#define PINMUX_GPIO152__FUNC_B1_MSDC0_DAT6 (MTK_PIN_NO(152) | 1) + +#define PINMUX_GPIO153__FUNC_B_GPIO153 (MTK_PIN_NO(153) | 0) +#define PINMUX_GPIO153__FUNC_B1_MSDC0_DAT5 (MTK_PIN_NO(153) | 1) + +#define PINMUX_GPIO154__FUNC_B_GPIO154 (MTK_PIN_NO(154) | 0) +#define PINMUX_GPIO154__FUNC_B1_MSDC0_DAT4 (MTK_PIN_NO(154) | 1) + +#define PINMUX_GPIO155__FUNC_B_GPIO155 (MTK_PIN_NO(155) | 0) +#define PINMUX_GPIO155__FUNC_O_MSDC0_RSTB (MTK_PIN_NO(155) | 1) + +#define PINMUX_GPIO156__FUNC_B_GPIO156 (MTK_PIN_NO(156) | 0) +#define PINMUX_GPIO156__FUNC_B1_MSDC0_CMD (MTK_PIN_NO(156) | 1) + +#define PINMUX_GPIO157__FUNC_B_GPIO157 (MTK_PIN_NO(157) | 0) +#define PINMUX_GPIO157__FUNC_B1_MSDC0_CLK (MTK_PIN_NO(157) | 1) + +#define PINMUX_GPIO158__FUNC_B_GPIO158 (MTK_PIN_NO(158) | 0) +#define PINMUX_GPIO158__FUNC_B1_MSDC0_DAT3 (MTK_PIN_NO(158) | 1) + +#define PINMUX_GPIO159__FUNC_B_GPIO159 (MTK_PIN_NO(159) | 0) +#define PINMUX_GPIO159__FUNC_B1_MSDC0_DAT2 (MTK_PIN_NO(159) | 1) + +#define PINMUX_GPIO160__FUNC_B_GPIO160 (MTK_PIN_NO(160) | 0) +#define PINMUX_GPIO160__FUNC_B1_MSDC0_DAT1 (MTK_PIN_NO(160) | 1) + +#define PINMUX_GPIO161__FUNC_B_GPIO161 (MTK_PIN_NO(161) | 0) +#define PINMUX_GPIO161__FUNC_B1_MSDC0_DAT0 (MTK_PIN_NO(161) | 1) + +#define PINMUX_GPIO162__FUNC_B_GPIO162 (MTK_PIN_NO(162) | 0) +#define PINMUX_GPIO162__FUNC_B0_MSDC0_DSL (MTK_PIN_NO(162) | 1) + +#define PINMUX_GPIO163__FUNC_B_GPIO163 (MTK_PIN_NO(163) | 0) +#define PINMUX_GPIO163__FUNC_B1_MSDC1_CMD (MTK_PIN_NO(163) | 1) +#define PINMUX_GPIO163__FUNC_O_SPDIF_OUT (MTK_PIN_NO(163) | 2) +#define PINMUX_GPIO163__FUNC_I1_MD32_0_JTAG_TMS (MTK_PIN_NO(163) | 3) +#define PINMUX_GPIO163__FUNC_I1_ADSP_JTAG0_TMS (MTK_PIN_NO(163) | 4) +#define PINMUX_GPIO163__FUNC_I1_SCP_JTAG0_TMS (MTK_PIN_NO(163) | 5) +#define PINMUX_GPIO163__FUNC_I1_CCU0_JTAG_TMS (MTK_PIN_NO(163) | 6) +#define PINMUX_GPIO163__FUNC_I0_IPU_JTAG_TMS (MTK_PIN_NO(163) | 7) + +#define PINMUX_GPIO164__FUNC_B_GPIO164 (MTK_PIN_NO(164) | 0) +#define PINMUX_GPIO164__FUNC_B1_MSDC1_CLK (MTK_PIN_NO(164) | 1) +#define PINMUX_GPIO164__FUNC_I0_SPDIF_IN0 (MTK_PIN_NO(164) | 2) +#define PINMUX_GPIO164__FUNC_I1_MD32_0_JTAG_TCK (MTK_PIN_NO(164) | 3) +#define PINMUX_GPIO164__FUNC_I0_ADSP_JTAG0_TCK (MTK_PIN_NO(164) | 4) +#define PINMUX_GPIO164__FUNC_I1_SCP_JTAG0_TCK (MTK_PIN_NO(164) | 5) +#define PINMUX_GPIO164__FUNC_I1_CCU0_JTAG_TCK (MTK_PIN_NO(164) | 6) +#define PINMUX_GPIO164__FUNC_I0_IPU_JTAG_TCK (MTK_PIN_NO(164) | 7) + +#define PINMUX_GPIO165__FUNC_B_GPIO165 (MTK_PIN_NO(165) | 0) +#define PINMUX_GPIO165__FUNC_B1_MSDC1_DAT0 (MTK_PIN_NO(165) | 1) +#define PINMUX_GPIO165__FUNC_I0_SPDIF_IN1 (MTK_PIN_NO(165) | 2) +#define PINMUX_GPIO165__FUNC_I1_MD32_0_JTAG_TDI (MTK_PIN_NO(165) | 3) +#define PINMUX_GPIO165__FUNC_I1_ADSP_JTAG0_TDI (MTK_PIN_NO(165) | 4) +#define PINMUX_GPIO165__FUNC_I1_SCP_JTAG0_TDI (MTK_PIN_NO(165) | 5) +#define PINMUX_GPIO165__FUNC_I1_CCU0_JTAG_TDI (MTK_PIN_NO(165) | 6) +#define PINMUX_GPIO165__FUNC_I0_IPU_JTAG_TDI (MTK_PIN_NO(165) | 7) + +#define PINMUX_GPIO166__FUNC_B_GPIO166 (MTK_PIN_NO(166) | 0) +#define PINMUX_GPIO166__FUNC_B1_MSDC1_DAT1 (MTK_PIN_NO(166) | 1) +#define PINMUX_GPIO166__FUNC_I0_SPDIF_IN2 (MTK_PIN_NO(166) | 2) +#define PINMUX_GPIO166__FUNC_O_MD32_0_JTAG_TDO (MTK_PIN_NO(166) | 3) +#define PINMUX_GPIO166__FUNC_O_ADSP_JTAG0_TDO (MTK_PIN_NO(166) | 4) +#define PINMUX_GPIO166__FUNC_O_SCP_JTAG0_TDO (MTK_PIN_NO(166) | 5) +#define PINMUX_GPIO166__FUNC_O_CCU0_JTAG_TDO (MTK_PIN_NO(166) | 6) +#define PINMUX_GPIO166__FUNC_O_IPU_JTAG_TDO (MTK_PIN_NO(166) | 7) + +#define PINMUX_GPIO167__FUNC_B_GPIO167 (MTK_PIN_NO(167) | 0) +#define PINMUX_GPIO167__FUNC_B1_MSDC1_DAT2 (MTK_PIN_NO(167) | 1) +#define PINMUX_GPIO167__FUNC_O_PWM_0 (MTK_PIN_NO(167) | 2) +#define PINMUX_GPIO167__FUNC_I1_MD32_0_JTAG_TRST (MTK_PIN_NO(167) | 3) +#define PINMUX_GPIO167__FUNC_I1_ADSP_JTAG0_TRSTN (MTK_PIN_NO(167) | 4) +#define PINMUX_GPIO167__FUNC_I0_SCP_JTAG0_TRSTN (MTK_PIN_NO(167) | 5) +#define PINMUX_GPIO167__FUNC_I1_CCU0_JTAG_TRST (MTK_PIN_NO(167) | 6) +#define PINMUX_GPIO167__FUNC_I0_IPU_JTAG_TRST (MTK_PIN_NO(167) | 7) + +#define PINMUX_GPIO168__FUNC_B_GPIO168 (MTK_PIN_NO(168) | 0) +#define PINMUX_GPIO168__FUNC_B1_MSDC1_DAT3 (MTK_PIN_NO(168) | 1) +#define PINMUX_GPIO168__FUNC_O_PWM_1 (MTK_PIN_NO(168) | 2) +#define PINMUX_GPIO168__FUNC_O_CLKM0 (MTK_PIN_NO(168) | 3) + +#define PINMUX_GPIO169__FUNC_B_GPIO169 (MTK_PIN_NO(169) | 0) +#define PINMUX_GPIO169__FUNC_B1_MSDC2_CMD (MTK_PIN_NO(169) | 1) +#define PINMUX_GPIO169__FUNC_O_LVTS_FOUT (MTK_PIN_NO(169) | 2) +#define PINMUX_GPIO169__FUNC_I1_MD32_1_JTAG_TMS (MTK_PIN_NO(169) | 3) +#define PINMUX_GPIO169__FUNC_I0_UDI_TMS (MTK_PIN_NO(169) | 4) +#define PINMUX_GPIO169__FUNC_I0_VPU_UDI_TMS (MTK_PIN_NO(169) | 5) +#define PINMUX_GPIO169__FUNC_B0_TDMIN_MCK (MTK_PIN_NO(169) | 6) +#define PINMUX_GPIO169__FUNC_I1_SSPM_JTAG_TMS (MTK_PIN_NO(169) | 7) + +#define PINMUX_GPIO170__FUNC_B_GPIO170 (MTK_PIN_NO(170) | 0) +#define PINMUX_GPIO170__FUNC_B1_MSDC2_CLK (MTK_PIN_NO(170) | 1) +#define PINMUX_GPIO170__FUNC_O_LVTS_SDO (MTK_PIN_NO(170) | 2) +#define PINMUX_GPIO170__FUNC_I1_MD32_1_JTAG_TCK (MTK_PIN_NO(170) | 3) +#define PINMUX_GPIO170__FUNC_I0_UDI_TCK (MTK_PIN_NO(170) | 4) +#define PINMUX_GPIO170__FUNC_I0_VPU_UDI_TCK (MTK_PIN_NO(170) | 5) +#define PINMUX_GPIO170__FUNC_B0_TDMIN_BCK (MTK_PIN_NO(170) | 6) +#define PINMUX_GPIO170__FUNC_I1_SSPM_JTAG_TCK (MTK_PIN_NO(170) | 7) + +#define PINMUX_GPIO171__FUNC_B_GPIO171 (MTK_PIN_NO(171) | 0) +#define PINMUX_GPIO171__FUNC_B1_MSDC2_DAT0 (MTK_PIN_NO(171) | 1) +#define PINMUX_GPIO171__FUNC_I0_LVTS_26M (MTK_PIN_NO(171) | 2) +#define PINMUX_GPIO171__FUNC_I1_MD32_1_JTAG_TDI (MTK_PIN_NO(171) | 3) +#define PINMUX_GPIO171__FUNC_I0_UDI_TDI (MTK_PIN_NO(171) | 4) +#define PINMUX_GPIO171__FUNC_I0_VPU_UDI_TDI (MTK_PIN_NO(171) | 5) +#define PINMUX_GPIO171__FUNC_B0_TDMIN_LRCK (MTK_PIN_NO(171) | 6) +#define PINMUX_GPIO171__FUNC_I1_SSPM_JTAG_TDI (MTK_PIN_NO(171) | 7) + +#define PINMUX_GPIO172__FUNC_B_GPIO172 (MTK_PIN_NO(172) | 0) +#define PINMUX_GPIO172__FUNC_B1_MSDC2_DAT1 (MTK_PIN_NO(172) | 1) +#define PINMUX_GPIO172__FUNC_I0_LVTS_SCF (MTK_PIN_NO(172) | 2) +#define PINMUX_GPIO172__FUNC_O_MD32_1_JTAG_TDO (MTK_PIN_NO(172) | 3) +#define PINMUX_GPIO172__FUNC_O_UDI_TDO (MTK_PIN_NO(172) | 4) +#define PINMUX_GPIO172__FUNC_O_VPU_UDI_TDO (MTK_PIN_NO(172) | 5) +#define PINMUX_GPIO172__FUNC_I0_TDMIN_DI (MTK_PIN_NO(172) | 6) +#define PINMUX_GPIO172__FUNC_O_SSPM_JTAG_TDO (MTK_PIN_NO(172) | 7) + +#define PINMUX_GPIO173__FUNC_B_GPIO173 (MTK_PIN_NO(173) | 0) +#define PINMUX_GPIO173__FUNC_B1_MSDC2_DAT2 (MTK_PIN_NO(173) | 1) +#define PINMUX_GPIO173__FUNC_I0_LVTS_SCK (MTK_PIN_NO(173) | 2) +#define PINMUX_GPIO173__FUNC_I1_MD32_1_JTAG_TRST (MTK_PIN_NO(173) | 3) +#define PINMUX_GPIO173__FUNC_I0_UDI_NTRST (MTK_PIN_NO(173) | 4) +#define PINMUX_GPIO173__FUNC_I0_VPU_UDI_NTRST (MTK_PIN_NO(173) | 5) +#define PINMUX_GPIO173__FUNC_I0_SSPM_JTAG_TRSTN (MTK_PIN_NO(173) | 7) + +#define PINMUX_GPIO174__FUNC_B_GPIO174 (MTK_PIN_NO(174) | 0) +#define PINMUX_GPIO174__FUNC_B1_MSDC2_DAT3 (MTK_PIN_NO(174) | 1) +#define PINMUX_GPIO174__FUNC_I0_LVTS_SDI (MTK_PIN_NO(174) | 2) + +#define PINMUX_GPIO175__FUNC_B_GPIO175 (MTK_PIN_NO(175) | 0) +#define PINMUX_GPIO175__FUNC_B0_SPMI_M_SCL (MTK_PIN_NO(175) | 1) + +#define PINMUX_GPIO176__FUNC_B_GPIO176 (MTK_PIN_NO(176) | 0) +#define PINMUX_GPIO176__FUNC_B0_SPMI_M_SDA (MTK_PIN_NO(176) | 1) + +#endif /* __MEDIATEK_MT8188-PINFUNC_H */ From 11b918d90aebf87b7d317ec95c17b46716f43d57 Mon Sep 17 00:00:00 2001 From: "Hui.Liu" Date: Thu, 18 Aug 2022 15:50:12 +0800 Subject: [PATCH 061/401] pinctrl: mediatek: add mt8188 driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add pinctrl driver support for MediaTek SoC mt8188. Signed-off-by: Hui.Liu Reviewed-by: Nícolas F. R. A. Prado Link: https://lore.kernel.org/r/20220818075012.20880-3-hui.liu@mediatek.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/Kconfig | 12 + drivers/pinctrl/mediatek/Makefile | 1 + drivers/pinctrl/mediatek/pinctrl-mt8188.c | 1673 ++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-mt8188.h | 2259 +++++++++++++++++ 4 files changed, 3945 insertions(+) create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8188.c create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt8188.h diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig index 1600a2c18eee..fed02c6fea06 100644 --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -162,6 +162,18 @@ config PINCTRL_MT8186 default ARM64 && ARCH_MEDIATEK select PINCTRL_MTK_PARIS +config PINCTRL_MT8188 + bool "MediaTek MT8188 pin control" + depends on OF + depends on ARM64 || COMPILE_TEST + default ARM64 && ARCH_MEDIATEK + select PINCTRL_MTK_PARIS + help + Say yes here to support pin controller and gpio driver + on MediaTek MT8188 SoC. + In MTK platform, we support virtual gpio and use it to + map specific eint which doesn't have real gpio pin. + config PINCTRL_MT8192 bool "Mediatek MT8192 pin control" depends on OF diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile index c8f226ae36c9..53265404a39d 100644 --- a/drivers/pinctrl/mediatek/Makefile +++ b/drivers/pinctrl/mediatek/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_PINCTRL_MT8167) += pinctrl-mt8167.o obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o obj-$(CONFIG_PINCTRL_MT8186) += pinctrl-mt8186.o +obj-$(CONFIG_PINCTRL_MT8188) += pinctrl-mt8188.o obj-$(CONFIG_PINCTRL_MT8192) += pinctrl-mt8192.o obj-$(CONFIG_PINCTRL_MT8195) += pinctrl-mt8195.o obj-$(CONFIG_PINCTRL_MT8365) += pinctrl-mt8365.o diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8188.c b/drivers/pinctrl/mediatek/pinctrl-mt8188.c new file mode 100644 index 000000000000..d0e75c1b4417 --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mt8188.c @@ -0,0 +1,1673 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Hui Liu + * + */ + +#include +#include "pinctrl-mtk-mt8188.h" +#include "pinctrl-paris.h" + +/* MT8188 have multiple bases to program pin configuration listed as the below: + * iocfg[0]:0x10005000, iocfg[1]:0x11c00000, iocfg[2]:0x11e10000, + * iocfg[3]:0x11e20000, iocfg[4]:0x11ea0000 + * _i_based could be used to indicate what base the pin should be mapped into. + */ + +#define PIN_FIELD_BASE(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits) \ + PIN_FIELD_CALC(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits, \ + 32, 0) + +#define PINS_FIELD_BASE(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits) \ + PIN_FIELD_CALC(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits, \ + 32, 1) + +static const struct mtk_pin_field_calc mt8188_pin_mode_range[] = { + PIN_FIELD(0, 177, 0x0300, 0x10, 0, 4), +}; + +static const struct mtk_pin_field_calc mt8188_pin_dir_range[] = { + PIN_FIELD(0, 177, 0x0000, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_di_range[] = { + PIN_FIELD(0, 177, 0x0200, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_do_range[] = { + PIN_FIELD(0, 177, 0x0100, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_smt_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x0170, 0x10, 8, 1), + PIN_FIELD_BASE(1, 1, 1, 0x0170, 0x10, 9, 1), + PIN_FIELD_BASE(2, 2, 1, 0x0170, 0x10, 10, 1), + PIN_FIELD_BASE(3, 3, 1, 0x0170, 0x10, 11, 1), + PIN_FIELD_BASE(4, 4, 1, 0x0170, 0x10, 18, 1), + PIN_FIELD_BASE(5, 5, 1, 0x0170, 0x10, 18, 1), + PIN_FIELD_BASE(6, 6, 1, 0x0170, 0x10, 18, 1), + PIN_FIELD_BASE(7, 7, 1, 0x0170, 0x10, 12, 1), + PIN_FIELD_BASE(8, 8, 1, 0x0170, 0x10, 13, 1), + PIN_FIELD_BASE(9, 9, 1, 0x0170, 0x10, 14, 1), + PIN_FIELD_BASE(10, 10, 1, 0x0170, 0x10, 15, 1), + PIN_FIELD_BASE(11, 11, 1, 0x0170, 0x10, 19, 1), + PIN_FIELD_BASE(12, 12, 2, 0x0160, 0x10, 12, 1), + PIN_FIELD_BASE(13, 13, 2, 0x0160, 0x10, 13, 1), + PIN_FIELD_BASE(14, 14, 2, 0x0160, 0x10, 14, 1), + PIN_FIELD_BASE(15, 15, 2, 0x0160, 0x10, 15, 1), + PIN_FIELD_BASE(16, 16, 3, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(17, 17, 3, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(18, 18, 4, 0x00e0, 0x10, 9, 1), + PIN_FIELD_BASE(19, 19, 4, 0x00e0, 0x10, 9, 1), + PIN_FIELD_BASE(20, 20, 4, 0x00e0, 0x10, 9, 1), + PIN_FIELD_BASE(21, 21, 4, 0x00e0, 0x10, 9, 1), + PIN_FIELD_BASE(22, 22, 4, 0x00e0, 0x10, 0, 1), + PIN_FIELD_BASE(23, 23, 4, 0x00e0, 0x10, 1, 1), + PIN_FIELD_BASE(24, 24, 4, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(25, 25, 1, 0x0170, 0x10, 17, 1), + PIN_FIELD_BASE(26, 26, 1, 0x0170, 0x10, 17, 1), + PIN_FIELD_BASE(27, 27, 1, 0x0170, 0x10, 17, 1), + PIN_FIELD_BASE(28, 28, 1, 0x0170, 0x10, 18, 1), + PIN_FIELD_BASE(29, 29, 1, 0x0170, 0x10, 16, 1), + PIN_FIELD_BASE(30, 30, 1, 0x0170, 0x10, 17, 1), + PIN_FIELD_BASE(31, 31, 1, 0x0170, 0x10, 19, 1), + PIN_FIELD_BASE(32, 32, 1, 0x0170, 0x10, 19, 1), + PIN_FIELD_BASE(33, 33, 1, 0x0170, 0x10, 20, 1), + PIN_FIELD_BASE(34, 34, 1, 0x0170, 0x10, 20, 1), + PIN_FIELD_BASE(35, 35, 1, 0x0170, 0x10, 19, 1), + PIN_FIELD_BASE(36, 36, 1, 0x0170, 0x10, 20, 1), + PIN_FIELD_BASE(37, 37, 1, 0x0170, 0x10, 21, 1), + PIN_FIELD_BASE(38, 38, 1, 0x0170, 0x10, 20, 1), + PIN_FIELD_BASE(39, 39, 1, 0x0170, 0x10, 21, 1), + PIN_FIELD_BASE(40, 40, 1, 0x0170, 0x10, 21, 1), + PIN_FIELD_BASE(41, 41, 1, 0x0170, 0x10, 21, 1), + PIN_FIELD_BASE(42, 42, 2, 0x0160, 0x10, 21, 1), + PIN_FIELD_BASE(43, 43, 2, 0x0160, 0x10, 22, 1), + PIN_FIELD_BASE(44, 44, 2, 0x0160, 0x10, 21, 1), + PIN_FIELD_BASE(45, 45, 2, 0x0160, 0x10, 22, 1), + PIN_FIELD_BASE(46, 46, 3, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(47, 47, 1, 0x0170, 0x10, 16, 1), + PIN_FIELD_BASE(48, 48, 1, 0x0170, 0x10, 16, 1), + PIN_FIELD_BASE(49, 49, 1, 0x0170, 0x10, 16, 1), + PIN_FIELD_BASE(50, 50, 3, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(51, 51, 3, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(52, 52, 3, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(53, 53, 3, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(54, 54, 3, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(55, 55, 1, 0x0170, 0x10, 25, 1), + PIN_FIELD_BASE(56, 56, 1, 0x0170, 0x10, 28, 1), + PIN_FIELD_BASE(57, 57, 2, 0x0160, 0x10, 29, 1), + PIN_FIELD_BASE(58, 58, 2, 0x0160, 0x10, 31, 1), + PIN_FIELD_BASE(59, 59, 1, 0x0170, 0x10, 26, 1), + PIN_FIELD_BASE(60, 60, 1, 0x0170, 0x10, 29, 1), + PIN_FIELD_BASE(61, 61, 1, 0x0170, 0x10, 27, 1), + PIN_FIELD_BASE(62, 62, 1, 0x0170, 0x10, 30, 1), + PIN_FIELD_BASE(63, 63, 2, 0x0160, 0x10, 30, 1), + PIN_FIELD_BASE(64, 64, 2, 0x0170, 0x10, 0, 1), + PIN_FIELD_BASE(65, 65, 4, 0x00e0, 0x10, 10, 1), + PIN_FIELD_BASE(66, 66, 4, 0x00e0, 0x10, 12, 1), + PIN_FIELD_BASE(67, 67, 4, 0x00e0, 0x10, 11, 1), + PIN_FIELD_BASE(68, 68, 4, 0x00e0, 0x10, 13, 1), + PIN_FIELD_BASE(69, 69, 1, 0x0180, 0x10, 0, 1), + PIN_FIELD_BASE(70, 70, 1, 0x0170, 0x10, 31, 1), + PIN_FIELD_BASE(71, 71, 1, 0x0180, 0x10, 4, 1), + PIN_FIELD_BASE(72, 72, 1, 0x0180, 0x10, 3, 1), + PIN_FIELD_BASE(73, 73, 1, 0x0180, 0x10, 1, 1), + PIN_FIELD_BASE(74, 74, 1, 0x0180, 0x10, 2, 1), + PIN_FIELD_BASE(75, 75, 1, 0x0180, 0x10, 6, 1), + PIN_FIELD_BASE(76, 76, 1, 0x0180, 0x10, 5, 1), + PIN_FIELD_BASE(77, 77, 1, 0x0180, 0x10, 8, 1), + PIN_FIELD_BASE(78, 78, 1, 0x0180, 0x10, 7, 1), + PIN_FIELD_BASE(79, 79, 4, 0x00e0, 0x10, 15, 1), + PIN_FIELD_BASE(80, 80, 4, 0x00e0, 0x10, 14, 1), + PIN_FIELD_BASE(81, 81, 4, 0x00e0, 0x10, 17, 1), + PIN_FIELD_BASE(82, 82, 4, 0x00e0, 0x10, 16, 1), + PIN_FIELD_BASE(83, 83, 2, 0x0160, 0x10, 26, 1), + PIN_FIELD_BASE(84, 84, 2, 0x0160, 0x10, 26, 1), + PIN_FIELD_BASE(85, 85, 2, 0x0160, 0x10, 27, 1), + PIN_FIELD_BASE(86, 86, 2, 0x0160, 0x10, 17, 1), + PIN_FIELD_BASE(87, 87, 2, 0x0160, 0x10, 17, 1), + PIN_FIELD_BASE(88, 88, 2, 0x0160, 0x10, 17, 1), + PIN_FIELD_BASE(89, 89, 2, 0x0160, 0x10, 17, 1), + PIN_FIELD_BASE(90, 90, 2, 0x0160, 0x10, 27, 1), + PIN_FIELD_BASE(91, 91, 2, 0x0160, 0x10, 27, 1), + PIN_FIELD_BASE(92, 92, 2, 0x0160, 0x10, 18, 1), + PIN_FIELD_BASE(93, 93, 2, 0x0160, 0x10, 18, 1), + PIN_FIELD_BASE(94, 94, 2, 0x0160, 0x10, 18, 1), + PIN_FIELD_BASE(95, 95, 2, 0x0160, 0x10, 18, 1), + PIN_FIELD_BASE(96, 96, 2, 0x0160, 0x10, 22, 1), + PIN_FIELD_BASE(97, 97, 2, 0x0160, 0x10, 23, 1), + PIN_FIELD_BASE(98, 98, 2, 0x0160, 0x10, 24, 1), + PIN_FIELD_BASE(99, 99, 2, 0x0160, 0x10, 22, 1), + PIN_FIELD_BASE(100, 100, 2, 0x0160, 0x10, 16, 1), + PIN_FIELD_BASE(101, 101, 2, 0x0160, 0x10, 23, 1), + PIN_FIELD_BASE(102, 102, 2, 0x0160, 0x10, 23, 1), + PIN_FIELD_BASE(103, 103, 2, 0x0160, 0x10, 23, 1), + PIN_FIELD_BASE(104, 104, 2, 0x0160, 0x10, 24, 1), + PIN_FIELD_BASE(105, 105, 2, 0x0160, 0x10, 24, 1), + PIN_FIELD_BASE(106, 106, 2, 0x0160, 0x10, 24, 1), + PIN_FIELD_BASE(107, 107, 2, 0x0160, 0x10, 17, 1), + PIN_FIELD_BASE(108, 108, 2, 0x0160, 0x10, 17, 1), + PIN_FIELD_BASE(109, 109, 2, 0x0160, 0x10, 17, 1), + PIN_FIELD_BASE(110, 110, 2, 0x0160, 0x10, 17, 1), + PIN_FIELD_BASE(111, 111, 2, 0x0160, 0x10, 19, 1), + PIN_FIELD_BASE(112, 112, 2, 0x0160, 0x10, 19, 1), + PIN_FIELD_BASE(113, 113, 2, 0x0160, 0x10, 19, 1), + PIN_FIELD_BASE(114, 114, 2, 0x0160, 0x10, 19, 1), + PIN_FIELD_BASE(115, 115, 2, 0x0160, 0x10, 20, 1), + PIN_FIELD_BASE(116, 116, 2, 0x0160, 0x10, 20, 1), + PIN_FIELD_BASE(117, 117, 2, 0x0160, 0x10, 20, 1), + PIN_FIELD_BASE(118, 118, 2, 0x0160, 0x10, 20, 1), + PIN_FIELD_BASE(119, 119, 2, 0x0160, 0x10, 21, 1), + PIN_FIELD_BASE(120, 120, 2, 0x0160, 0x10, 21, 1), + PIN_FIELD_BASE(121, 121, 3, 0x00d0, 0x10, 6, 1), + PIN_FIELD_BASE(122, 122, 3, 0x00d0, 0x10, 9, 1), + PIN_FIELD_BASE(123, 123, 3, 0x00d0, 0x10, 8, 1), + PIN_FIELD_BASE(124, 124, 3, 0x00d0, 0x10, 7, 1), + PIN_FIELD_BASE(125, 125, 2, 0x0160, 0x10, 25, 1), + PIN_FIELD_BASE(126, 126, 2, 0x0160, 0x10, 25, 1), + PIN_FIELD_BASE(127, 127, 2, 0x0160, 0x10, 25, 1), + PIN_FIELD_BASE(128, 128, 2, 0x0160, 0x10, 25, 1), + PIN_FIELD_BASE(129, 129, 2, 0x0160, 0x10, 26, 1), + PIN_FIELD_BASE(130, 130, 2, 0x0160, 0x10, 26, 1), + PIN_FIELD_BASE(131, 131, 1, 0x0170, 0x10, 0, 1), + PIN_FIELD_BASE(132, 132, 1, 0x0170, 0x10, 1, 1), + PIN_FIELD_BASE(133, 133, 1, 0x0170, 0x10, 6, 1), + PIN_FIELD_BASE(134, 134, 1, 0x0170, 0x10, 7, 1), + PIN_FIELD_BASE(135, 135, 1, 0x0170, 0x10, 22, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0170, 0x10, 22, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0170, 0x10, 22, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0170, 0x10, 22, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0170, 0x10, 23, 1), + PIN_FIELD_BASE(140, 140, 1, 0x0170, 0x10, 23, 1), + PIN_FIELD_BASE(141, 141, 1, 0x0170, 0x10, 23, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0170, 0x10, 23, 1), + PIN_FIELD_BASE(143, 143, 1, 0x0170, 0x10, 2, 1), + PIN_FIELD_BASE(144, 144, 1, 0x0170, 0x10, 3, 1), + PIN_FIELD_BASE(145, 145, 1, 0x0170, 0x10, 4, 1), + PIN_FIELD_BASE(146, 146, 1, 0x0170, 0x10, 5, 1), + PIN_FIELD_BASE(147, 147, 1, 0x0170, 0x10, 24, 1), + PIN_FIELD_BASE(148, 148, 1, 0x0170, 0x10, 24, 1), + PIN_FIELD_BASE(149, 149, 1, 0x0170, 0x10, 24, 1), + PIN_FIELD_BASE(150, 150, 1, 0x0170, 0x10, 24, 1), + PIN_FIELD_BASE(151, 151, 2, 0x0160, 0x10, 9, 1), + PIN_FIELD_BASE(152, 152, 2, 0x0160, 0x10, 8, 1), + PIN_FIELD_BASE(153, 153, 2, 0x0160, 0x10, 7, 1), + PIN_FIELD_BASE(154, 154, 2, 0x0160, 0x10, 6, 1), + PIN_FIELD_BASE(155, 155, 2, 0x0160, 0x10, 11, 1), + PIN_FIELD_BASE(156, 156, 2, 0x0160, 0x10, 1, 1), + PIN_FIELD_BASE(157, 157, 2, 0x0160, 0x10, 0, 1), + PIN_FIELD_BASE(158, 158, 2, 0x0160, 0x10, 5, 1), + PIN_FIELD_BASE(159, 159, 2, 0x0160, 0x10, 4, 1), + PIN_FIELD_BASE(160, 160, 2, 0x0160, 0x10, 3, 1), + PIN_FIELD_BASE(161, 161, 2, 0x0160, 0x10, 2, 1), + PIN_FIELD_BASE(162, 162, 2, 0x0160, 0x10, 10, 1), + PIN_FIELD_BASE(163, 163, 4, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(164, 164, 4, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(165, 165, 4, 0x00e0, 0x10, 5, 1), + PIN_FIELD_BASE(166, 166, 4, 0x00e0, 0x10, 6, 1), + PIN_FIELD_BASE(167, 167, 4, 0x00e0, 0x10, 7, 1), + PIN_FIELD_BASE(168, 168, 4, 0x00e0, 0x10, 8, 1), + PIN_FIELD_BASE(169, 169, 3, 0x00d0, 0x10, 1, 1), + PIN_FIELD_BASE(170, 170, 3, 0x00d0, 0x10, 0, 1), + PIN_FIELD_BASE(171, 171, 3, 0x00d0, 0x10, 2, 1), + PIN_FIELD_BASE(172, 172, 3, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 3, 0x00d0, 0x10, 4, 1), + PIN_FIELD_BASE(174, 174, 3, 0x00d0, 0x10, 5, 1), + PIN_FIELD_BASE(175, 175, 2, 0x0160, 0x10, 28, 1), + PIN_FIELD_BASE(176, 176, 2, 0x0160, 0x10, 28, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_ies_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x0080, 0x10, 26, 1), + PIN_FIELD_BASE(1, 1, 1, 0x0080, 0x10, 27, 1), + PIN_FIELD_BASE(2, 2, 1, 0x0080, 0x10, 28, 1), + PIN_FIELD_BASE(3, 3, 1, 0x0080, 0x10, 29, 1), + PIN_FIELD_BASE(4, 4, 1, 0x0080, 0x10, 30, 1), + PIN_FIELD_BASE(5, 5, 1, 0x0080, 0x10, 31, 1), + PIN_FIELD_BASE(6, 6, 1, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(7, 7, 1, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(8, 8, 1, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(9, 9, 1, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(10, 10, 1, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(11, 11, 1, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(12, 12, 2, 0x0070, 0x10, 24, 1), + PIN_FIELD_BASE(13, 13, 2, 0x0070, 0x10, 25, 1), + PIN_FIELD_BASE(14, 14, 2, 0x0070, 0x10, 26, 1), + PIN_FIELD_BASE(15, 15, 2, 0x0070, 0x10, 27, 1), + PIN_FIELD_BASE(16, 16, 3, 0x0040, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 3, 0x0040, 0x10, 2, 1), + PIN_FIELD_BASE(18, 18, 4, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(19, 19, 4, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(20, 20, 4, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(21, 21, 4, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 4, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(23, 23, 4, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(24, 24, 4, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(25, 25, 1, 0x0080, 0x10, 23, 1), + PIN_FIELD_BASE(26, 26, 1, 0x0080, 0x10, 22, 1), + PIN_FIELD_BASE(27, 27, 1, 0x0080, 0x10, 25, 1), + PIN_FIELD_BASE(28, 28, 1, 0x0080, 0x10, 24, 1), + PIN_FIELD_BASE(29, 29, 1, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(30, 30, 1, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(31, 31, 1, 0x0090, 0x10, 31, 1), + PIN_FIELD_BASE(32, 32, 1, 0x0090, 0x10, 30, 1), + PIN_FIELD_BASE(33, 33, 1, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(34, 34, 1, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(35, 35, 1, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(36, 36, 1, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 1, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(38, 38, 1, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(39, 39, 1, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(40, 40, 1, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(41, 41, 1, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(42, 42, 2, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(43, 43, 2, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(44, 44, 2, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(45, 45, 2, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(46, 46, 3, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(47, 47, 1, 0x0090, 0x10, 13, 1), + PIN_FIELD_BASE(48, 48, 1, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(49, 49, 1, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(50, 50, 3, 0x0040, 0x10, 5, 1), + PIN_FIELD_BASE(51, 51, 3, 0x0040, 0x10, 4, 1), + PIN_FIELD_BASE(52, 52, 3, 0x0040, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 3, 0x0040, 0x10, 6, 1), + PIN_FIELD_BASE(54, 54, 3, 0x0040, 0x10, 7, 1), + PIN_FIELD_BASE(55, 55, 1, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(56, 56, 1, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(57, 57, 2, 0x0080, 0x10, 22, 1), + PIN_FIELD_BASE(58, 58, 2, 0x0080, 0x10, 25, 1), + PIN_FIELD_BASE(59, 59, 1, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(60, 60, 1, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(61, 61, 1, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(62, 62, 1, 0x0090, 0x10, 19, 1), + PIN_FIELD_BASE(63, 63, 2, 0x0080, 0x10, 23, 1), + PIN_FIELD_BASE(64, 64, 2, 0x0080, 0x10, 26, 1), + PIN_FIELD_BASE(65, 65, 4, 0x0050, 0x10, 13, 1), + PIN_FIELD_BASE(66, 66, 4, 0x0050, 0x10, 15, 1), + PIN_FIELD_BASE(67, 67, 4, 0x0050, 0x10, 14, 1), + PIN_FIELD_BASE(68, 68, 4, 0x0050, 0x10, 16, 1), + PIN_FIELD_BASE(69, 69, 1, 0x0090, 0x10, 21, 1), + PIN_FIELD_BASE(70, 70, 1, 0x0090, 0x10, 20, 1), + PIN_FIELD_BASE(71, 71, 1, 0x0090, 0x10, 25, 1), + PIN_FIELD_BASE(72, 72, 1, 0x0090, 0x10, 24, 1), + PIN_FIELD_BASE(73, 73, 1, 0x0090, 0x10, 22, 1), + PIN_FIELD_BASE(74, 74, 1, 0x0090, 0x10, 23, 1), + PIN_FIELD_BASE(75, 75, 1, 0x0090, 0x10, 27, 1), + PIN_FIELD_BASE(76, 76, 1, 0x0090, 0x10, 26, 1), + PIN_FIELD_BASE(77, 77, 1, 0x0090, 0x10, 29, 1), + PIN_FIELD_BASE(78, 78, 1, 0x0090, 0x10, 28, 1), + PIN_FIELD_BASE(79, 79, 4, 0x0050, 0x10, 18, 1), + PIN_FIELD_BASE(80, 80, 4, 0x0050, 0x10, 17, 1), + PIN_FIELD_BASE(81, 81, 4, 0x0050, 0x10, 20, 1), + PIN_FIELD_BASE(82, 82, 4, 0x0050, 0x10, 19, 1), + PIN_FIELD_BASE(83, 83, 2, 0x0080, 0x10, 30, 1), + PIN_FIELD_BASE(84, 84, 2, 0x0080, 0x10, 29, 1), + PIN_FIELD_BASE(85, 85, 2, 0x0080, 0x10, 31, 1), + PIN_FIELD_BASE(86, 86, 2, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, 2, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, 2, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(89, 89, 2, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(90, 90, 2, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(91, 91, 2, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(92, 92, 2, 0x0080, 0x10, 19, 1), + PIN_FIELD_BASE(93, 93, 2, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(94, 94, 2, 0x0080, 0x10, 21, 1), + PIN_FIELD_BASE(95, 95, 2, 0x0080, 0x10, 20, 1), + PIN_FIELD_BASE(96, 96, 2, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(97, 97, 2, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(98, 98, 2, 0x0080, 0x10, 24, 1), + PIN_FIELD_BASE(99, 99, 2, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(100, 100, 2, 0x0080, 0x10, 17, 1), + PIN_FIELD_BASE(101, 101, 2, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(102, 102, 2, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(103, 103, 2, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(104, 104, 2, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(105, 105, 2, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(106, 106, 2, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(107, 107, 2, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(108, 108, 2, 0x0070, 0x10, 28, 1), + PIN_FIELD_BASE(109, 109, 2, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(110, 110, 2, 0x0070, 0x10, 29, 1), + PIN_FIELD_BASE(111, 111, 2, 0x0070, 0x10, 30, 1), + PIN_FIELD_BASE(112, 112, 2, 0x0070, 0x10, 31, 1), + PIN_FIELD_BASE(113, 113, 2, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(114, 114, 2, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(115, 115, 2, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(116, 116, 2, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(117, 117, 2, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(118, 118, 2, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(119, 119, 2, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(120, 120, 2, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(121, 121, 3, 0x0040, 0x10, 14, 1), + PIN_FIELD_BASE(122, 122, 3, 0x0040, 0x10, 17, 1), + PIN_FIELD_BASE(123, 123, 3, 0x0040, 0x10, 16, 1), + PIN_FIELD_BASE(124, 124, 3, 0x0040, 0x10, 15, 1), + PIN_FIELD_BASE(125, 125, 2, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(126, 126, 2, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(127, 127, 2, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(128, 128, 2, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(129, 129, 2, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(130, 130, 2, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(131, 131, 1, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(132, 132, 1, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(133, 133, 1, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(134, 134, 1, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(135, 135, 1, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0080, 0x10, 17, 1), + PIN_FIELD_BASE(140, 140, 1, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(141, 141, 1, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(143, 143, 1, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(144, 144, 1, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(145, 145, 1, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(146, 146, 1, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(147, 147, 1, 0x0080, 0x10, 20, 1), + PIN_FIELD_BASE(148, 148, 1, 0x0080, 0x10, 21, 1), + PIN_FIELD_BASE(149, 149, 1, 0x0080, 0x10, 19, 1), + PIN_FIELD_BASE(150, 150, 1, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(151, 151, 2, 0x0070, 0x10, 21, 1), + PIN_FIELD_BASE(152, 152, 2, 0x0070, 0x10, 20, 1), + PIN_FIELD_BASE(153, 153, 2, 0x0070, 0x10, 19, 1), + PIN_FIELD_BASE(154, 154, 2, 0x0070, 0x10, 18, 1), + PIN_FIELD_BASE(155, 155, 2, 0x0070, 0x10, 23, 1), + PIN_FIELD_BASE(156, 156, 2, 0x0070, 0x10, 13, 1), + PIN_FIELD_BASE(157, 157, 2, 0x0070, 0x10, 12, 1), + PIN_FIELD_BASE(158, 158, 2, 0x0070, 0x10, 17, 1), + PIN_FIELD_BASE(159, 159, 2, 0x0070, 0x10, 16, 1), + PIN_FIELD_BASE(160, 160, 2, 0x0070, 0x10, 15, 1), + PIN_FIELD_BASE(161, 161, 2, 0x0070, 0x10, 14, 1), + PIN_FIELD_BASE(162, 162, 2, 0x0070, 0x10, 22, 1), + PIN_FIELD_BASE(163, 163, 4, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(164, 164, 4, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(165, 165, 4, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(166, 166, 4, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(167, 167, 4, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(168, 168, 4, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(169, 169, 3, 0x0040, 0x10, 9, 1), + PIN_FIELD_BASE(170, 170, 3, 0x0040, 0x10, 8, 1), + PIN_FIELD_BASE(171, 171, 3, 0x0040, 0x10, 10, 1), + PIN_FIELD_BASE(172, 172, 3, 0x0040, 0x10, 11, 1), + PIN_FIELD_BASE(173, 173, 3, 0x0040, 0x10, 12, 1), + PIN_FIELD_BASE(174, 174, 3, 0x0040, 0x10, 13, 1), + PIN_FIELD_BASE(175, 175, 2, 0x0080, 0x10, 27, 1), + PIN_FIELD_BASE(176, 176, 2, 0x0080, 0x10, 28, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_tdsel_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x01b0, 0x10, 0, 4), + PIN_FIELD_BASE(1, 1, 1, 0x01b0, 0x10, 4, 4), + PIN_FIELD_BASE(2, 2, 1, 0x01b0, 0x10, 8, 4), + PIN_FIELD_BASE(3, 3, 1, 0x01b0, 0x10, 12, 4), + PIN_FIELD_BASE(4, 4, 1, 0x01c0, 0x10, 16, 4), + PIN_FIELD_BASE(5, 5, 1, 0x01c0, 0x10, 20, 4), + PIN_FIELD_BASE(6, 6, 1, 0x01c0, 0x10, 20, 4), + PIN_FIELD_BASE(7, 7, 1, 0x01b0, 0x10, 16, 4), + PIN_FIELD_BASE(8, 8, 1, 0x01b0, 0x10, 20, 4), + PIN_FIELD_BASE(9, 9, 1, 0x01b0, 0x10, 24, 4), + PIN_FIELD_BASE(10, 10, 1, 0x01b0, 0x10, 28, 4), + PIN_FIELD_BASE(11, 11, 1, 0x01c0, 0x10, 20, 4), + PIN_FIELD_BASE(12, 12, 2, 0x0190, 0x10, 16, 4), + PIN_FIELD_BASE(13, 13, 2, 0x0190, 0x10, 20, 4), + PIN_FIELD_BASE(14, 14, 2, 0x0190, 0x10, 24, 4), + PIN_FIELD_BASE(15, 15, 2, 0x0190, 0x10, 28, 4), + PIN_FIELD_BASE(16, 16, 3, 0x0100, 0x10, 8, 4), + PIN_FIELD_BASE(17, 17, 3, 0x0100, 0x10, 8, 4), + PIN_FIELD_BASE(18, 18, 4, 0x0110, 0x10, 4, 4), + PIN_FIELD_BASE(19, 19, 4, 0x0110, 0x10, 8, 4), + PIN_FIELD_BASE(20, 20, 4, 0x0110, 0x10, 8, 4), + PIN_FIELD_BASE(21, 21, 4, 0x0110, 0x10, 8, 4), + PIN_FIELD_BASE(22, 22, 4, 0x0100, 0x10, 0, 4), + PIN_FIELD_BASE(23, 23, 4, 0x0100, 0x10, 4, 4), + PIN_FIELD_BASE(24, 24, 4, 0x0100, 0x10, 8, 4), + PIN_FIELD_BASE(25, 25, 1, 0x01c0, 0x10, 8, 4), + PIN_FIELD_BASE(26, 26, 1, 0x01c0, 0x10, 8, 4), + PIN_FIELD_BASE(27, 27, 1, 0x01c0, 0x10, 8, 4), + PIN_FIELD_BASE(28, 28, 1, 0x01c0, 0x10, 12, 4), + PIN_FIELD_BASE(29, 29, 1, 0x01c0, 0x10, 0, 4), + PIN_FIELD_BASE(30, 30, 1, 0x01c0, 0x10, 8, 4), + PIN_FIELD_BASE(31, 31, 1, 0x01c0, 0x10, 20, 4), + PIN_FIELD_BASE(32, 32, 1, 0x01c0, 0x10, 24, 4), + PIN_FIELD_BASE(33, 33, 1, 0x01c0, 0x10, 24, 4), + PIN_FIELD_BASE(34, 34, 1, 0x01c0, 0x10, 28, 4), + PIN_FIELD_BASE(35, 35, 1, 0x01c0, 0x10, 24, 4), + PIN_FIELD_BASE(36, 36, 1, 0x01c0, 0x10, 24, 4), + PIN_FIELD_BASE(37, 37, 1, 0x01c0, 0x10, 28, 4), + PIN_FIELD_BASE(38, 38, 1, 0x01c0, 0x10, 28, 4), + PIN_FIELD_BASE(39, 39, 1, 0x01c0, 0x10, 28, 4), + PIN_FIELD_BASE(40, 40, 1, 0x01d0, 0x10, 0, 4), + PIN_FIELD_BASE(41, 41, 1, 0x01d0, 0x10, 0, 4), + PIN_FIELD_BASE(42, 42, 2, 0x01a0, 0x10, 16, 4), + PIN_FIELD_BASE(43, 43, 2, 0x01a0, 0x10, 20, 4), + PIN_FIELD_BASE(44, 44, 2, 0x01a0, 0x10, 16, 4), + PIN_FIELD_BASE(45, 45, 2, 0x01a0, 0x10, 20, 4), + PIN_FIELD_BASE(46, 46, 3, 0x0100, 0x10, 8, 4), + PIN_FIELD_BASE(47, 47, 1, 0x01c0, 0x10, 0, 4), + PIN_FIELD_BASE(48, 48, 1, 0x01c0, 0x10, 0, 4), + PIN_FIELD_BASE(49, 49, 1, 0x01c0, 0x10, 0, 4), + PIN_FIELD_BASE(50, 50, 3, 0x0100, 0x10, 8, 4), + PIN_FIELD_BASE(51, 51, 3, 0x0100, 0x10, 12, 4), + PIN_FIELD_BASE(52, 52, 3, 0x0100, 0x10, 12, 4), + PIN_FIELD_BASE(53, 53, 3, 0x0100, 0x10, 12, 4), + PIN_FIELD_BASE(54, 54, 3, 0x0100, 0x10, 12, 4), + PIN_FIELD_BASE(55, 55, 1, 0x01c0, 0x10, 12, 4), + PIN_FIELD_BASE(56, 56, 1, 0x01c0, 0x10, 12, 4), + PIN_FIELD_BASE(57, 57, 2, 0x01a0, 0x10, 24, 4), + PIN_FIELD_BASE(58, 58, 2, 0x01a0, 0x10, 24, 4), + PIN_FIELD_BASE(59, 59, 1, 0x01c0, 0x10, 16, 4), + PIN_FIELD_BASE(60, 60, 1, 0x01c0, 0x10, 12, 4), + PIN_FIELD_BASE(61, 61, 1, 0x01c0, 0x10, 16, 4), + PIN_FIELD_BASE(62, 62, 1, 0x01c0, 0x10, 16, 4), + PIN_FIELD_BASE(63, 63, 2, 0x01a0, 0x10, 20, 4), + PIN_FIELD_BASE(64, 64, 2, 0x01a0, 0x10, 20, 4), + PIN_FIELD_BASE(65, 65, 4, 0x0110, 0x10, 12, 4), + PIN_FIELD_BASE(66, 66, 4, 0x0110, 0x10, 8, 4), + PIN_FIELD_BASE(67, 67, 4, 0x0110, 0x10, 12, 4), + PIN_FIELD_BASE(68, 68, 4, 0x0110, 0x10, 12, 4), + PIN_FIELD_BASE(69, 69, 1, 0x01d0, 0x10, 16, 4), + PIN_FIELD_BASE(70, 70, 1, 0x01d0, 0x10, 12, 4), + PIN_FIELD_BASE(71, 71, 1, 0x01e0, 0x10, 0, 4), + PIN_FIELD_BASE(72, 72, 1, 0x01d0, 0x10, 28, 4), + PIN_FIELD_BASE(73, 73, 1, 0x01d0, 0x10, 20, 4), + PIN_FIELD_BASE(74, 74, 1, 0x01d0, 0x10, 24, 4), + PIN_FIELD_BASE(75, 75, 1, 0x01e0, 0x10, 8, 4), + PIN_FIELD_BASE(76, 76, 1, 0x01e0, 0x10, 4, 4), + PIN_FIELD_BASE(77, 77, 1, 0x01e0, 0x10, 16, 4), + PIN_FIELD_BASE(78, 78, 1, 0x01e0, 0x10, 12, 4), + PIN_FIELD_BASE(79, 79, 4, 0x0110, 0x10, 20, 4), + PIN_FIELD_BASE(80, 80, 4, 0x0110, 0x10, 16, 4), + PIN_FIELD_BASE(81, 81, 4, 0x0110, 0x10, 28, 4), + PIN_FIELD_BASE(82, 82, 4, 0x0110, 0x10, 24, 4), + PIN_FIELD_BASE(83, 83, 2, 0x01b0, 0x10, 8, 4), + PIN_FIELD_BASE(84, 84, 2, 0x01b0, 0x10, 8, 4), + PIN_FIELD_BASE(85, 85, 2, 0x01b0, 0x10, 12, 4), + PIN_FIELD_BASE(86, 86, 2, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(87, 87, 2, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(88, 88, 2, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(89, 89, 2, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(90, 90, 2, 0x01b0, 0x10, 12, 4), + PIN_FIELD_BASE(91, 91, 2, 0x01b0, 0x10, 12, 4), + PIN_FIELD_BASE(92, 92, 2, 0x01a0, 0x10, 4, 4), + PIN_FIELD_BASE(93, 93, 2, 0x01a0, 0x10, 4, 4), + PIN_FIELD_BASE(94, 94, 2, 0x01a0, 0x10, 4, 4), + PIN_FIELD_BASE(95, 95, 2, 0x01a0, 0x10, 4, 4), + PIN_FIELD_BASE(96, 96, 2, 0x01a0, 0x10, 24, 4), + PIN_FIELD_BASE(97, 97, 2, 0x01a0, 0x10, 28, 4), + PIN_FIELD_BASE(98, 98, 2, 0x01b0, 0x10, 0, 4), + PIN_FIELD_BASE(99, 99, 2, 0x01a0, 0x10, 24, 4), + PIN_FIELD_BASE(100, 100, 2, 0x01b0, 0x10, 20, 4), + PIN_FIELD_BASE(101, 101, 2, 0x01a0, 0x10, 28, 4), + PIN_FIELD_BASE(102, 102, 2, 0x01a0, 0x10, 28, 4), + PIN_FIELD_BASE(103, 103, 2, 0x01a0, 0x10, 28, 4), + PIN_FIELD_BASE(104, 104, 2, 0x01b0, 0x10, 0, 4), + PIN_FIELD_BASE(105, 105, 2, 0x01b0, 0x10, 0, 4), + PIN_FIELD_BASE(106, 106, 2, 0x01b0, 0x10, 0, 4), + PIN_FIELD_BASE(107, 107, 2, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(108, 108, 2, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(109, 109, 2, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(110, 110, 2, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(111, 111, 2, 0x01a0, 0x10, 8, 4), + PIN_FIELD_BASE(112, 112, 2, 0x01a0, 0x10, 8, 4), + PIN_FIELD_BASE(113, 113, 2, 0x01a0, 0x10, 8, 4), + PIN_FIELD_BASE(114, 114, 2, 0x01a0, 0x10, 8, 4), + PIN_FIELD_BASE(115, 115, 2, 0x01a0, 0x10, 12, 4), + PIN_FIELD_BASE(116, 116, 2, 0x01a0, 0x10, 12, 4), + PIN_FIELD_BASE(117, 117, 2, 0x01a0, 0x10, 12, 4), + PIN_FIELD_BASE(118, 118, 2, 0x01a0, 0x10, 12, 4), + PIN_FIELD_BASE(119, 119, 2, 0x01a0, 0x10, 16, 4), + PIN_FIELD_BASE(120, 120, 2, 0x01a0, 0x10, 16, 4), + PIN_FIELD_BASE(121, 121, 3, 0x00f0, 0x10, 24, 4), + PIN_FIELD_BASE(122, 122, 3, 0x0100, 0x10, 4, 4), + PIN_FIELD_BASE(123, 123, 3, 0x0100, 0x10, 0, 4), + PIN_FIELD_BASE(124, 124, 3, 0x00f0, 0x10, 28, 4), + PIN_FIELD_BASE(125, 125, 2, 0x01b0, 0x10, 4, 4), + PIN_FIELD_BASE(126, 126, 2, 0x01b0, 0x10, 4, 4), + PIN_FIELD_BASE(127, 127, 2, 0x01b0, 0x10, 4, 4), + PIN_FIELD_BASE(128, 128, 2, 0x01b0, 0x10, 4, 4), + PIN_FIELD_BASE(129, 129, 2, 0x01b0, 0x10, 8, 4), + PIN_FIELD_BASE(130, 130, 2, 0x01b0, 0x10, 8, 4), + PIN_FIELD_BASE(131, 131, 1, 0x01a0, 0x10, 0, 4), + PIN_FIELD_BASE(132, 132, 1, 0x01a0, 0x10, 20, 4), + PIN_FIELD_BASE(133, 133, 1, 0x01a0, 0x10, 24, 4), + PIN_FIELD_BASE(134, 134, 1, 0x01a0, 0x10, 28, 4), + PIN_FIELD_BASE(135, 135, 1, 0x01d0, 0x10, 0, 4), + PIN_FIELD_BASE(136, 136, 1, 0x01d0, 0x10, 0, 4), + PIN_FIELD_BASE(137, 137, 1, 0x01d0, 0x10, 4, 4), + PIN_FIELD_BASE(138, 138, 1, 0x01d0, 0x10, 4, 4), + PIN_FIELD_BASE(139, 139, 1, 0x01d0, 0x10, 4, 4), + PIN_FIELD_BASE(140, 140, 1, 0x01d0, 0x10, 4, 4), + PIN_FIELD_BASE(141, 141, 1, 0x01d0, 0x10, 8, 4), + PIN_FIELD_BASE(142, 142, 1, 0x01d0, 0x10, 8, 4), + PIN_FIELD_BASE(143, 143, 1, 0x01a0, 0x10, 4, 4), + PIN_FIELD_BASE(144, 144, 1, 0x01a0, 0x10, 8, 4), + PIN_FIELD_BASE(145, 145, 1, 0x01a0, 0x10, 12, 4), + PIN_FIELD_BASE(146, 146, 1, 0x01a0, 0x10, 16, 4), + PIN_FIELD_BASE(147, 147, 1, 0x01d0, 0x10, 8, 4), + PIN_FIELD_BASE(148, 148, 1, 0x01d0, 0x10, 8, 4), + PIN_FIELD_BASE(149, 149, 1, 0x01c0, 0x10, 4, 4), + PIN_FIELD_BASE(150, 150, 1, 0x01c0, 0x10, 4, 4), + PIN_FIELD_BASE(151, 151, 2, 0x0190, 0x10, 4, 4), + PIN_FIELD_BASE(152, 152, 2, 0x0190, 0x10, 0, 4), + PIN_FIELD_BASE(153, 153, 2, 0x0180, 0x10, 28, 4), + PIN_FIELD_BASE(154, 154, 2, 0x0180, 0x10, 24, 4), + PIN_FIELD_BASE(155, 155, 2, 0x0190, 0x10, 12, 4), + PIN_FIELD_BASE(156, 156, 2, 0x0180, 0x10, 4, 4), + PIN_FIELD_BASE(157, 157, 2, 0x0180, 0x10, 0, 4), + PIN_FIELD_BASE(158, 158, 2, 0x0180, 0x10, 20, 4), + PIN_FIELD_BASE(159, 159, 2, 0x0180, 0x10, 16, 4), + PIN_FIELD_BASE(160, 160, 2, 0x0180, 0x10, 12, 4), + PIN_FIELD_BASE(161, 161, 2, 0x0180, 0x10, 8, 4), + PIN_FIELD_BASE(162, 162, 2, 0x0190, 0x10, 8, 4), + PIN_FIELD_BASE(163, 163, 4, 0x0100, 0x10, 16, 4), + PIN_FIELD_BASE(164, 164, 4, 0x0100, 0x10, 12, 4), + PIN_FIELD_BASE(165, 165, 4, 0x0100, 0x10, 20, 4), + PIN_FIELD_BASE(166, 166, 4, 0x0100, 0x10, 24, 4), + PIN_FIELD_BASE(167, 167, 4, 0x0100, 0x10, 28, 4), + PIN_FIELD_BASE(168, 168, 4, 0x0110, 0x10, 0, 4), + PIN_FIELD_BASE(169, 169, 3, 0x00f0, 0x10, 4, 4), + PIN_FIELD_BASE(170, 170, 3, 0x00f0, 0x10, 0, 4), + PIN_FIELD_BASE(171, 171, 3, 0x00f0, 0x10, 8, 4), + PIN_FIELD_BASE(172, 172, 3, 0x00f0, 0x10, 12, 4), + PIN_FIELD_BASE(173, 173, 3, 0x00f0, 0x10, 16, 4), + PIN_FIELD_BASE(174, 174, 3, 0x00f0, 0x10, 20, 4), + PIN_FIELD_BASE(175, 175, 2, 0x01b0, 0x10, 16, 4), + PIN_FIELD_BASE(176, 176, 2, 0x01b0, 0x10, 16, 4), +}; + +static const struct mtk_pin_field_calc mt8188_pin_rdsel_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x0130, 0x10, 18, 2), + PIN_FIELD_BASE(1, 1, 1, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(2, 2, 1, 0x0130, 0x10, 22, 2), + PIN_FIELD_BASE(3, 3, 1, 0x0130, 0x10, 24, 2), + PIN_FIELD_BASE(4, 4, 1, 0x0140, 0x10, 14, 2), + PIN_FIELD_BASE(5, 5, 1, 0x0140, 0x10, 16, 2), + PIN_FIELD_BASE(6, 6, 1, 0x0140, 0x10, 16, 2), + PIN_FIELD_BASE(7, 7, 1, 0x0130, 0x10, 26, 2), + PIN_FIELD_BASE(8, 8, 1, 0x0130, 0x10, 28, 2), + PIN_FIELD_BASE(9, 9, 1, 0x0130, 0x10, 30, 2), + PIN_FIELD_BASE(10, 10, 1, 0x0140, 0x10, 0, 2), + PIN_FIELD_BASE(11, 11, 1, 0x0140, 0x10, 16, 2), + PIN_FIELD_BASE(12, 12, 2, 0x0130, 0x10, 12, 2), + PIN_FIELD_BASE(13, 13, 2, 0x0130, 0x10, 14, 2), + PIN_FIELD_BASE(14, 14, 2, 0x0130, 0x10, 16, 2), + PIN_FIELD_BASE(15, 15, 2, 0x0130, 0x10, 18, 2), + PIN_FIELD_BASE(16, 16, 3, 0x00b0, 0x10, 14, 2), + PIN_FIELD_BASE(17, 17, 3, 0x00b0, 0x10, 14, 2), + PIN_FIELD_BASE(18, 18, 4, 0x00c0, 0x10, 12, 2), + PIN_FIELD_BASE(19, 19, 4, 0x00c0, 0x10, 12, 2), + PIN_FIELD_BASE(20, 20, 4, 0x00c0, 0x10, 12, 2), + PIN_FIELD_BASE(21, 21, 4, 0x00c0, 0x10, 12, 2), + PIN_FIELD_BASE(22, 22, 4, 0x00b0, 0x10, 0, 2), + PIN_FIELD_BASE(23, 23, 4, 0x00b0, 0x10, 2, 2), + PIN_FIELD_BASE(24, 24, 4, 0x00b0, 0x10, 4, 2), + PIN_FIELD_BASE(25, 25, 1, 0x0140, 0x10, 10, 2), + PIN_FIELD_BASE(26, 26, 1, 0x0140, 0x10, 10, 2), + PIN_FIELD_BASE(27, 27, 1, 0x0140, 0x10, 10, 2), + PIN_FIELD_BASE(28, 28, 1, 0x0140, 0x10, 12, 2), + PIN_FIELD_BASE(29, 29, 1, 0x0140, 0x10, 2, 2), + PIN_FIELD_BASE(30, 30, 1, 0x0140, 0x10, 10, 2), + PIN_FIELD_BASE(31, 31, 1, 0x0140, 0x10, 16, 2), + PIN_FIELD_BASE(32, 32, 1, 0x0140, 0x10, 18, 2), + PIN_FIELD_BASE(33, 33, 1, 0x0140, 0x10, 18, 2), + PIN_FIELD_BASE(34, 34, 1, 0x0140, 0x10, 20, 2), + PIN_FIELD_BASE(35, 35, 1, 0x0140, 0x10, 18, 2), + PIN_FIELD_BASE(36, 36, 1, 0x0140, 0x10, 18, 2), + PIN_FIELD_BASE(37, 37, 1, 0x0140, 0x10, 20, 2), + PIN_FIELD_BASE(38, 38, 1, 0x0140, 0x10, 20, 2), + PIN_FIELD_BASE(39, 39, 1, 0x0140, 0x10, 20, 2), + PIN_FIELD_BASE(40, 40, 1, 0x0140, 0x10, 22, 2), + PIN_FIELD_BASE(41, 41, 1, 0x0140, 0x10, 22, 2), + PIN_FIELD_BASE(42, 42, 2, 0x0130, 0x10, 30, 2), + PIN_FIELD_BASE(43, 43, 2, 0x0140, 0x10, 0, 2), + PIN_FIELD_BASE(44, 44, 2, 0x0130, 0x10, 30, 2), + PIN_FIELD_BASE(45, 45, 2, 0x0140, 0x10, 0, 2), + PIN_FIELD_BASE(46, 46, 3, 0x00b0, 0x10, 14, 2), + PIN_FIELD_BASE(47, 47, 1, 0x0140, 0x10, 2, 2), + PIN_FIELD_BASE(48, 48, 1, 0x0140, 0x10, 2, 2), + PIN_FIELD_BASE(49, 49, 1, 0x0140, 0x10, 2, 2), + PIN_FIELD_BASE(50, 50, 3, 0x00b0, 0x10, 14, 2), + PIN_FIELD_BASE(51, 51, 3, 0x00b0, 0x10, 16, 2), + PIN_FIELD_BASE(52, 52, 3, 0x00b0, 0x10, 16, 2), + PIN_FIELD_BASE(53, 53, 3, 0x00b0, 0x10, 16, 2), + PIN_FIELD_BASE(54, 54, 3, 0x00b0, 0x10, 16, 2), + PIN_FIELD_BASE(55, 55, 1, 0x0140, 0x10, 12, 2), + PIN_FIELD_BASE(56, 56, 1, 0x0140, 0x10, 12, 2), + PIN_FIELD_BASE(57, 57, 2, 0x0140, 0x10, 2, 2), + PIN_FIELD_BASE(58, 58, 2, 0x0140, 0x10, 2, 2), + PIN_FIELD_BASE(59, 59, 1, 0x0140, 0x10, 14, 2), + PIN_FIELD_BASE(60, 60, 1, 0x0140, 0x10, 12, 2), + PIN_FIELD_BASE(61, 61, 1, 0x0140, 0x10, 14, 2), + PIN_FIELD_BASE(62, 62, 1, 0x0140, 0x10, 14, 2), + PIN_FIELD_BASE(63, 63, 2, 0x0140, 0x10, 0, 2), + PIN_FIELD_BASE(64, 64, 2, 0x0140, 0x10, 0, 2), + PIN_FIELD_BASE(65, 65, 4, 0x00c0, 0x10, 14, 2), + PIN_FIELD_BASE(66, 66, 4, 0x00c0, 0x10, 14, 2), + PIN_FIELD_BASE(67, 67, 4, 0x00c0, 0x10, 14, 2), + PIN_FIELD_BASE(68, 68, 4, 0x00c0, 0x10, 14, 2), + PIN_FIELD_BASE(69, 69, 1, 0x0150, 0x10, 14, 2), + PIN_FIELD_BASE(70, 70, 1, 0x0150, 0x10, 12, 2), + PIN_FIELD_BASE(71, 71, 1, 0x0150, 0x10, 22, 2), + PIN_FIELD_BASE(72, 72, 1, 0x0150, 0x10, 20, 2), + PIN_FIELD_BASE(73, 73, 1, 0x0150, 0x10, 16, 2), + PIN_FIELD_BASE(74, 74, 1, 0x0150, 0x10, 18, 2), + PIN_FIELD_BASE(75, 75, 1, 0x0150, 0x10, 26, 2), + PIN_FIELD_BASE(76, 76, 1, 0x0150, 0x10, 24, 2), + PIN_FIELD_BASE(77, 77, 1, 0x0150, 0x10, 30, 2), + PIN_FIELD_BASE(78, 78, 1, 0x0150, 0x10, 28, 2), + PIN_FIELD_BASE(79, 79, 4, 0x00c0, 0x10, 18, 2), + PIN_FIELD_BASE(80, 80, 4, 0x00c0, 0x10, 16, 2), + PIN_FIELD_BASE(81, 81, 4, 0x00c0, 0x10, 22, 2), + PIN_FIELD_BASE(82, 82, 4, 0x00c0, 0x10, 20, 2), + PIN_FIELD_BASE(83, 83, 2, 0x0140, 0x10, 10, 2), + PIN_FIELD_BASE(84, 84, 2, 0x0140, 0x10, 10, 2), + PIN_FIELD_BASE(85, 85, 2, 0x0140, 0x10, 12, 2), + PIN_FIELD_BASE(86, 86, 2, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(87, 87, 2, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(88, 88, 2, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(89, 89, 2, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(90, 90, 2, 0x0140, 0x10, 12, 2), + PIN_FIELD_BASE(91, 91, 2, 0x0140, 0x10, 12, 2), + PIN_FIELD_BASE(92, 92, 2, 0x0130, 0x10, 22, 2), + PIN_FIELD_BASE(93, 93, 2, 0x0130, 0x10, 22, 2), + PIN_FIELD_BASE(94, 94, 2, 0x0130, 0x10, 22, 2), + PIN_FIELD_BASE(95, 95, 2, 0x0130, 0x10, 22, 2), + PIN_FIELD_BASE(96, 96, 2, 0x0140, 0x10, 2, 2), + PIN_FIELD_BASE(97, 97, 2, 0x0140, 0x10, 4, 2), + PIN_FIELD_BASE(98, 98, 2, 0x0140, 0x10, 6, 2), + PIN_FIELD_BASE(99, 99, 2, 0x0140, 0x10, 2, 2), + PIN_FIELD_BASE(100, 100, 2, 0x0140, 0x10, 16, 2), + PIN_FIELD_BASE(101, 101, 2, 0x0140, 0x10, 4, 2), + PIN_FIELD_BASE(102, 102, 2, 0x0140, 0x10, 4, 2), + PIN_FIELD_BASE(103, 103, 2, 0x0140, 0x10, 4, 2), + PIN_FIELD_BASE(104, 104, 2, 0x0140, 0x10, 6, 2), + PIN_FIELD_BASE(105, 105, 2, 0x0140, 0x10, 6, 2), + PIN_FIELD_BASE(106, 106, 2, 0x0140, 0x10, 6, 2), + PIN_FIELD_BASE(107, 107, 2, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(108, 108, 2, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(109, 109, 2, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(110, 110, 2, 0x0130, 0x10, 20, 2), + PIN_FIELD_BASE(111, 111, 2, 0x0130, 0x10, 24, 2), + PIN_FIELD_BASE(112, 112, 2, 0x0130, 0x10, 24, 2), + PIN_FIELD_BASE(113, 113, 2, 0x0130, 0x10, 24, 2), + PIN_FIELD_BASE(114, 114, 2, 0x0130, 0x10, 24, 2), + PIN_FIELD_BASE(115, 115, 2, 0x0130, 0x10, 28, 2), + PIN_FIELD_BASE(116, 116, 2, 0x0130, 0x10, 28, 2), + PIN_FIELD_BASE(117, 117, 2, 0x0130, 0x10, 28, 2), + PIN_FIELD_BASE(118, 118, 2, 0x0130, 0x10, 28, 2), + PIN_FIELD_BASE(119, 119, 2, 0x0130, 0x10, 30, 2), + PIN_FIELD_BASE(120, 120, 2, 0x0130, 0x10, 30, 2), + PIN_FIELD_BASE(121, 121, 3, 0x00b0, 0x10, 6, 2), + PIN_FIELD_BASE(122, 122, 3, 0x00b0, 0x10, 12, 2), + PIN_FIELD_BASE(123, 123, 3, 0x00b0, 0x10, 10, 2), + PIN_FIELD_BASE(124, 124, 3, 0x00b0, 0x10, 8, 2), + PIN_FIELD_BASE(125, 125, 2, 0x0140, 0x10, 8, 2), + PIN_FIELD_BASE(126, 126, 2, 0x0140, 0x10, 8, 2), + PIN_FIELD_BASE(127, 127, 2, 0x0140, 0x10, 8, 2), + PIN_FIELD_BASE(128, 128, 2, 0x0140, 0x10, 8, 2), + PIN_FIELD_BASE(129, 129, 2, 0x0140, 0x10, 10, 2), + PIN_FIELD_BASE(130, 130, 2, 0x0140, 0x10, 10, 2), + PIN_FIELD_BASE(131, 131, 1, 0x0120, 0x10, 0, 6), + PIN_FIELD_BASE(132, 132, 1, 0x0130, 0x10, 0, 6), + PIN_FIELD_BASE(133, 133, 1, 0x0130, 0x10, 6, 6), + PIN_FIELD_BASE(134, 134, 1, 0x0130, 0x10, 12, 6), + PIN_FIELD_BASE(135, 135, 1, 0x0140, 0x10, 24, 6), + PIN_FIELD_BASE(136, 136, 1, 0x0140, 0x10, 24, 6), + PIN_FIELD_BASE(137, 137, 1, 0x0150, 0x10, 0, 6), + PIN_FIELD_BASE(138, 138, 1, 0x0150, 0x10, 0, 6), + PIN_FIELD_BASE(139, 139, 1, 0x0150, 0x10, 0, 6), + PIN_FIELD_BASE(140, 140, 1, 0x0150, 0x10, 0, 6), + PIN_FIELD_BASE(141, 141, 1, 0x0150, 0x10, 6, 6), + PIN_FIELD_BASE(142, 142, 1, 0x0150, 0x10, 6, 6), + PIN_FIELD_BASE(143, 143, 1, 0x0120, 0x10, 6, 6), + PIN_FIELD_BASE(144, 144, 1, 0x0120, 0x10, 12, 6), + PIN_FIELD_BASE(145, 145, 1, 0x0120, 0x10, 18, 6), + PIN_FIELD_BASE(146, 146, 1, 0x0120, 0x10, 24, 6), + PIN_FIELD_BASE(147, 147, 1, 0x0150, 0x10, 6, 6), + PIN_FIELD_BASE(148, 148, 1, 0x0150, 0x10, 6, 6), + PIN_FIELD_BASE(149, 149, 1, 0x0140, 0x10, 4, 6), + PIN_FIELD_BASE(150, 150, 1, 0x0140, 0x10, 4, 6), + PIN_FIELD_BASE(151, 151, 2, 0x0120, 0x10, 24, 6), + PIN_FIELD_BASE(152, 152, 2, 0x0120, 0x10, 18, 6), + PIN_FIELD_BASE(153, 153, 2, 0x0120, 0x10, 12, 6), + PIN_FIELD_BASE(154, 154, 2, 0x0120, 0x10, 6, 6), + PIN_FIELD_BASE(155, 155, 2, 0x0130, 0x10, 6, 6), + PIN_FIELD_BASE(156, 156, 2, 0x0110, 0x10, 6, 6), + PIN_FIELD_BASE(157, 157, 2, 0x0110, 0x10, 0, 6), + PIN_FIELD_BASE(158, 158, 2, 0x0120, 0x10, 0, 6), + PIN_FIELD_BASE(159, 159, 2, 0x0110, 0x10, 24, 6), + PIN_FIELD_BASE(160, 160, 2, 0x0110, 0x10, 18, 6), + PIN_FIELD_BASE(161, 161, 2, 0x0110, 0x10, 12, 6), + PIN_FIELD_BASE(162, 162, 2, 0x0130, 0x10, 0, 6), + PIN_FIELD_BASE(163, 163, 4, 0x00b0, 0x10, 12, 6), + PIN_FIELD_BASE(164, 164, 4, 0x00b0, 0x10, 6, 6), + PIN_FIELD_BASE(165, 165, 4, 0x00b0, 0x10, 18, 6), + PIN_FIELD_BASE(166, 166, 4, 0x00b0, 0x10, 24, 6), + PIN_FIELD_BASE(167, 167, 4, 0x00c0, 0x10, 0, 6), + PIN_FIELD_BASE(168, 168, 4, 0x00c0, 0x10, 6, 6), + PIN_FIELD_BASE(169, 169, 3, 0x00a0, 0x10, 6, 6), + PIN_FIELD_BASE(170, 170, 3, 0x00a0, 0x10, 0, 6), + PIN_FIELD_BASE(171, 171, 3, 0x00a0, 0x10, 12, 6), + PIN_FIELD_BASE(172, 172, 3, 0x00a0, 0x10, 18, 6), + PIN_FIELD_BASE(173, 173, 3, 0x00a0, 0x10, 24, 6), + PIN_FIELD_BASE(174, 174, 3, 0x00b0, 0x10, 0, 6), + PIN_FIELD_BASE(175, 175, 2, 0x0140, 0x10, 14, 2), + PIN_FIELD_BASE(176, 176, 2, 0x0140, 0x10, 14, 2), +}; + +static const struct mtk_pin_field_calc mt8188_pin_pupd_range[] = { + PIN_FIELD_BASE(42, 42, 2, 0x00c0, 0x10, 12, 1), + PIN_FIELD_BASE(43, 43, 2, 0x00c0, 0x10, 13, 1), + PIN_FIELD_BASE(44, 44, 2, 0x00c0, 0x10, 14, 1), + PIN_FIELD_BASE(45, 45, 2, 0x00c0, 0x10, 15, 1), + PIN_FIELD_BASE(131, 131, 1, 0x00d0, 0x10, 1, 1), + PIN_FIELD_BASE(132, 132, 1, 0x00d0, 0x10, 2, 1), + PIN_FIELD_BASE(133, 133, 1, 0x00d0, 0x10, 9, 1), + PIN_FIELD_BASE(134, 134, 1, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(135, 135, 1, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(136, 136, 1, 0x00d0, 0x10, 12, 1), + PIN_FIELD_BASE(137, 137, 1, 0x00d0, 0x10, 13, 1), + PIN_FIELD_BASE(138, 138, 1, 0x00d0, 0x10, 14, 1), + PIN_FIELD_BASE(139, 139, 1, 0x00d0, 0x10, 15, 1), + PIN_FIELD_BASE(140, 140, 1, 0x00d0, 0x10, 16, 1), + PIN_FIELD_BASE(141, 141, 1, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(142, 142, 1, 0x00d0, 0x10, 4, 1), + PIN_FIELD_BASE(143, 143, 1, 0x00d0, 0x10, 5, 1), + PIN_FIELD_BASE(144, 144, 1, 0x00d0, 0x10, 6, 1), + PIN_FIELD_BASE(145, 145, 1, 0x00d0, 0x10, 7, 1), + PIN_FIELD_BASE(146, 146, 1, 0x00d0, 0x10, 8, 1), + PIN_FIELD_BASE(147, 147, 1, 0x00d0, 0x10, 18, 1), + PIN_FIELD_BASE(148, 148, 1, 0x00d0, 0x10, 19, 1), + PIN_FIELD_BASE(149, 149, 1, 0x00d0, 0x10, 17, 1), + PIN_FIELD_BASE(150, 150, 1, 0x00d0, 0x10, 0, 1), + PIN_FIELD_BASE(151, 151, 2, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(152, 152, 2, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(153, 153, 2, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(154, 154, 2, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(155, 155, 2, 0x00c0, 0x10, 11, 1), + PIN_FIELD_BASE(156, 156, 2, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(157, 157, 2, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(158, 158, 2, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(159, 159, 2, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(160, 160, 2, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(161, 161, 2, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(162, 162, 2, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(163, 163, 4, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(164, 164, 4, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(165, 165, 4, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(166, 166, 4, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(167, 167, 4, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(168, 168, 4, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(169, 169, 3, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(170, 170, 3, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(171, 171, 3, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(172, 172, 3, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 3, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(174, 174, 3, 0x0060, 0x10, 5, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_r0_range[] = { + PIN_FIELD_BASE(42, 42, 2, 0x00f0, 0x10, 12, 1), + PIN_FIELD_BASE(43, 43, 2, 0x00f0, 0x10, 13, 1), + PIN_FIELD_BASE(44, 44, 2, 0x00f0, 0x10, 14, 1), + PIN_FIELD_BASE(45, 45, 2, 0x00f0, 0x10, 15, 1), + PIN_FIELD_BASE(131, 131, 1, 0x0100, 0x10, 1, 1), + PIN_FIELD_BASE(132, 132, 1, 0x0100, 0x10, 2, 1), + PIN_FIELD_BASE(133, 133, 1, 0x0100, 0x10, 9, 1), + PIN_FIELD_BASE(134, 134, 1, 0x0100, 0x10, 10, 1), + PIN_FIELD_BASE(135, 135, 1, 0x0100, 0x10, 11, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0100, 0x10, 12, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0100, 0x10, 13, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0100, 0x10, 14, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0100, 0x10, 15, 1), + PIN_FIELD_BASE(140, 140, 1, 0x0100, 0x10, 16, 1), + PIN_FIELD_BASE(141, 141, 1, 0x0100, 0x10, 3, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0100, 0x10, 4, 1), + PIN_FIELD_BASE(143, 143, 1, 0x0100, 0x10, 5, 1), + PIN_FIELD_BASE(144, 144, 1, 0x0100, 0x10, 6, 1), + PIN_FIELD_BASE(145, 145, 1, 0x0100, 0x10, 7, 1), + PIN_FIELD_BASE(146, 146, 1, 0x0100, 0x10, 8, 1), + PIN_FIELD_BASE(147, 147, 1, 0x0100, 0x10, 18, 1), + PIN_FIELD_BASE(148, 148, 1, 0x0100, 0x10, 19, 1), + PIN_FIELD_BASE(149, 149, 1, 0x0100, 0x10, 17, 1), + PIN_FIELD_BASE(150, 150, 1, 0x0100, 0x10, 0, 1), + PIN_FIELD_BASE(151, 151, 2, 0x00f0, 0x10, 9, 1), + PIN_FIELD_BASE(152, 152, 2, 0x00f0, 0x10, 8, 1), + PIN_FIELD_BASE(153, 153, 2, 0x00f0, 0x10, 7, 1), + PIN_FIELD_BASE(154, 154, 2, 0x00f0, 0x10, 6, 1), + PIN_FIELD_BASE(155, 155, 2, 0x00f0, 0x10, 11, 1), + PIN_FIELD_BASE(156, 156, 2, 0x00f0, 0x10, 1, 1), + PIN_FIELD_BASE(157, 157, 2, 0x00f0, 0x10, 0, 1), + PIN_FIELD_BASE(158, 158, 2, 0x00f0, 0x10, 5, 1), + PIN_FIELD_BASE(159, 159, 2, 0x00f0, 0x10, 4, 1), + PIN_FIELD_BASE(160, 160, 2, 0x00f0, 0x10, 3, 1), + PIN_FIELD_BASE(161, 161, 2, 0x00f0, 0x10, 2, 1), + PIN_FIELD_BASE(162, 162, 2, 0x00f0, 0x10, 10, 1), + PIN_FIELD_BASE(163, 163, 4, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(164, 164, 4, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(165, 165, 4, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(166, 166, 4, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(167, 167, 4, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(168, 168, 4, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(169, 169, 3, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(170, 170, 3, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(171, 171, 3, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(172, 172, 3, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 3, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(174, 174, 3, 0x0080, 0x10, 5, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_r1_range[] = { + PIN_FIELD_BASE(42, 42, 2, 0x0100, 0x10, 12, 1), + PIN_FIELD_BASE(43, 43, 2, 0x0100, 0x10, 13, 1), + PIN_FIELD_BASE(44, 44, 2, 0x0100, 0x10, 14, 1), + PIN_FIELD_BASE(45, 45, 2, 0x0100, 0x10, 15, 1), + PIN_FIELD_BASE(131, 131, 1, 0x0110, 0x10, 1, 1), + PIN_FIELD_BASE(132, 132, 1, 0x0110, 0x10, 2, 1), + PIN_FIELD_BASE(133, 133, 1, 0x0110, 0x10, 9, 1), + PIN_FIELD_BASE(134, 134, 1, 0x0110, 0x10, 10, 1), + PIN_FIELD_BASE(135, 135, 1, 0x0110, 0x10, 11, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0110, 0x10, 12, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0110, 0x10, 13, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0110, 0x10, 14, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0110, 0x10, 15, 1), + PIN_FIELD_BASE(140, 140, 1, 0x0110, 0x10, 16, 1), + PIN_FIELD_BASE(141, 141, 1, 0x0110, 0x10, 3, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0110, 0x10, 4, 1), + PIN_FIELD_BASE(143, 143, 1, 0x0110, 0x10, 5, 1), + PIN_FIELD_BASE(144, 144, 1, 0x0110, 0x10, 6, 1), + PIN_FIELD_BASE(145, 145, 1, 0x0110, 0x10, 7, 1), + PIN_FIELD_BASE(146, 146, 1, 0x0110, 0x10, 8, 1), + PIN_FIELD_BASE(147, 147, 1, 0x0110, 0x10, 18, 1), + PIN_FIELD_BASE(148, 148, 1, 0x0110, 0x10, 19, 1), + PIN_FIELD_BASE(149, 149, 1, 0x0110, 0x10, 17, 1), + PIN_FIELD_BASE(150, 150, 1, 0x0110, 0x10, 0, 1), + PIN_FIELD_BASE(151, 151, 2, 0x0100, 0x10, 9, 1), + PIN_FIELD_BASE(152, 152, 2, 0x0100, 0x10, 8, 1), + PIN_FIELD_BASE(153, 153, 2, 0x0100, 0x10, 7, 1), + PIN_FIELD_BASE(154, 154, 2, 0x0100, 0x10, 6, 1), + PIN_FIELD_BASE(155, 155, 2, 0x0100, 0x10, 11, 1), + PIN_FIELD_BASE(156, 156, 2, 0x0100, 0x10, 1, 1), + PIN_FIELD_BASE(157, 157, 2, 0x0100, 0x10, 0, 1), + PIN_FIELD_BASE(158, 158, 2, 0x0100, 0x10, 5, 1), + PIN_FIELD_BASE(159, 159, 2, 0x0100, 0x10, 4, 1), + PIN_FIELD_BASE(160, 160, 2, 0x0100, 0x10, 3, 1), + PIN_FIELD_BASE(161, 161, 2, 0x0100, 0x10, 2, 1), + PIN_FIELD_BASE(162, 162, 2, 0x0100, 0x10, 10, 1), + PIN_FIELD_BASE(163, 163, 4, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(164, 164, 4, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(165, 165, 4, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(166, 166, 4, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(167, 167, 4, 0x00a0, 0x10, 4, 1), + PIN_FIELD_BASE(168, 168, 4, 0x00a0, 0x10, 5, 1), + PIN_FIELD_BASE(169, 169, 3, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(170, 170, 3, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(171, 171, 3, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(172, 172, 3, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 3, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(174, 174, 3, 0x0090, 0x10, 5, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_pu_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x00e0, 0x10, 6, 1), + PIN_FIELD_BASE(1, 1, 1, 0x00e0, 0x10, 7, 1), + PIN_FIELD_BASE(2, 2, 1, 0x00e0, 0x10, 8, 1), + PIN_FIELD_BASE(3, 3, 1, 0x00e0, 0x10, 9, 1), + PIN_FIELD_BASE(4, 4, 1, 0x00e0, 0x10, 10, 1), + PIN_FIELD_BASE(5, 5, 1, 0x00e0, 0x10, 11, 1), + PIN_FIELD_BASE(6, 6, 1, 0x00e0, 0x10, 12, 1), + PIN_FIELD_BASE(7, 7, 1, 0x00e0, 0x10, 13, 1), + PIN_FIELD_BASE(8, 8, 1, 0x00e0, 0x10, 14, 1), + PIN_FIELD_BASE(9, 9, 1, 0x00e0, 0x10, 15, 1), + PIN_FIELD_BASE(10, 10, 1, 0x00e0, 0x10, 16, 1), + PIN_FIELD_BASE(11, 11, 1, 0x00e0, 0x10, 17, 1), + PIN_FIELD_BASE(12, 12, 2, 0x00d0, 0x10, 12, 1), + PIN_FIELD_BASE(13, 13, 2, 0x00d0, 0x10, 13, 1), + PIN_FIELD_BASE(14, 14, 2, 0x00d0, 0x10, 14, 1), + PIN_FIELD_BASE(15, 15, 2, 0x00d0, 0x10, 15, 1), + PIN_FIELD_BASE(16, 16, 3, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 3, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(18, 18, 4, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(19, 19, 4, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(20, 20, 4, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(21, 21, 4, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 4, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(23, 23, 4, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(24, 24, 4, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(25, 25, 1, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(26, 26, 1, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(27, 27, 1, 0x00e0, 0x10, 5, 1), + PIN_FIELD_BASE(28, 28, 1, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(29, 29, 1, 0x00e0, 0x10, 0, 1), + PIN_FIELD_BASE(30, 30, 1, 0x00e0, 0x10, 1, 1), + PIN_FIELD_BASE(31, 31, 1, 0x00f0, 0x10, 11, 1), + PIN_FIELD_BASE(32, 32, 1, 0x00f0, 0x10, 10, 1), + PIN_FIELD_BASE(33, 33, 1, 0x00f0, 0x10, 13, 1), + PIN_FIELD_BASE(34, 34, 1, 0x00f0, 0x10, 12, 1), + PIN_FIELD_BASE(35, 35, 1, 0x00f0, 0x10, 15, 1), + PIN_FIELD_BASE(36, 36, 1, 0x00f0, 0x10, 14, 1), + PIN_FIELD_BASE(37, 37, 1, 0x00e0, 0x10, 21, 1), + PIN_FIELD_BASE(38, 38, 1, 0x00e0, 0x10, 18, 1), + PIN_FIELD_BASE(39, 39, 1, 0x00e0, 0x10, 19, 1), + PIN_FIELD_BASE(40, 40, 1, 0x00e0, 0x10, 20, 1), + PIN_FIELD_BASE(41, 41, 1, 0x00e0, 0x10, 22, 1), + PIN_FIELD_BASE(46, 46, 3, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(47, 47, 1, 0x00e0, 0x10, 25, 1), + PIN_FIELD_BASE(48, 48, 1, 0x00e0, 0x10, 24, 1), + PIN_FIELD_BASE(49, 49, 1, 0x00e0, 0x10, 23, 1), + PIN_FIELD_BASE(50, 50, 3, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(51, 51, 3, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(52, 52, 3, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 3, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(54, 54, 3, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(55, 55, 1, 0x00e0, 0x10, 26, 1), + PIN_FIELD_BASE(56, 56, 1, 0x00e0, 0x10, 29, 1), + PIN_FIELD_BASE(57, 57, 2, 0x00e0, 0x10, 6, 1), + PIN_FIELD_BASE(58, 58, 2, 0x00e0, 0x10, 9, 1), + PIN_FIELD_BASE(59, 59, 1, 0x00e0, 0x10, 27, 1), + PIN_FIELD_BASE(60, 60, 1, 0x00e0, 0x10, 30, 1), + PIN_FIELD_BASE(61, 61, 1, 0x00e0, 0x10, 28, 1), + PIN_FIELD_BASE(62, 62, 1, 0x00e0, 0x10, 31, 1), + PIN_FIELD_BASE(63, 63, 2, 0x00e0, 0x10, 7, 1), + PIN_FIELD_BASE(64, 64, 2, 0x00e0, 0x10, 10, 1), + PIN_FIELD_BASE(65, 65, 4, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(66, 66, 4, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(67, 67, 4, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(68, 68, 4, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(69, 69, 1, 0x00f0, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, 1, 0x00f0, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, 1, 0x00f0, 0x10, 5, 1), + PIN_FIELD_BASE(72, 72, 1, 0x00f0, 0x10, 4, 1), + PIN_FIELD_BASE(73, 73, 1, 0x00f0, 0x10, 2, 1), + PIN_FIELD_BASE(74, 74, 1, 0x00f0, 0x10, 3, 1), + PIN_FIELD_BASE(75, 75, 1, 0x00f0, 0x10, 7, 1), + PIN_FIELD_BASE(76, 76, 1, 0x00f0, 0x10, 6, 1), + PIN_FIELD_BASE(77, 77, 1, 0x00f0, 0x10, 9, 1), + PIN_FIELD_BASE(78, 78, 1, 0x00f0, 0x10, 8, 1), + PIN_FIELD_BASE(79, 79, 4, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(80, 80, 4, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(81, 81, 4, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(82, 82, 4, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(83, 83, 2, 0x00e0, 0x10, 16, 1), + PIN_FIELD_BASE(84, 84, 2, 0x00e0, 0x10, 15, 1), + PIN_FIELD_BASE(85, 85, 2, 0x00e0, 0x10, 17, 1), + PIN_FIELD_BASE(86, 86, 2, 0x00e0, 0x10, 19, 1), + PIN_FIELD_BASE(87, 87, 2, 0x00e0, 0x10, 18, 1), + PIN_FIELD_BASE(88, 88, 2, 0x00e0, 0x10, 20, 1), + PIN_FIELD_BASE(89, 89, 2, 0x00e0, 0x10, 22, 1), + PIN_FIELD_BASE(90, 90, 2, 0x00e0, 0x10, 21, 1), + PIN_FIELD_BASE(91, 91, 2, 0x00e0, 0x10, 23, 1), + PIN_FIELD_BASE(92, 92, 2, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(93, 93, 2, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(94, 94, 2, 0x00e0, 0x10, 5, 1), + PIN_FIELD_BASE(95, 95, 2, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(96, 96, 2, 0x00d0, 0x10, 31, 1), + PIN_FIELD_BASE(97, 97, 2, 0x00e0, 0x10, 0, 1), + PIN_FIELD_BASE(98, 98, 2, 0x00e0, 0x10, 8, 1), + PIN_FIELD_BASE(99, 99, 2, 0x00d0, 0x10, 30, 1), + PIN_FIELD_BASE(100, 100, 2, 0x00e0, 0x10, 1, 1), + PIN_FIELD_BASE(101, 101, 2, 0x00d0, 0x10, 0, 1), + PIN_FIELD_BASE(102, 102, 2, 0x00d0, 0x10, 5, 1), + PIN_FIELD_BASE(103, 103, 2, 0x00d0, 0x10, 3, 1), + PIN_FIELD_BASE(104, 104, 2, 0x00d0, 0x10, 4, 1), + PIN_FIELD_BASE(105, 105, 2, 0x00d0, 0x10, 1, 1), + PIN_FIELD_BASE(106, 106, 2, 0x00d0, 0x10, 2, 1), + PIN_FIELD_BASE(107, 107, 2, 0x00d0, 0x10, 21, 1), + PIN_FIELD_BASE(108, 108, 2, 0x00d0, 0x10, 16, 1), + PIN_FIELD_BASE(109, 109, 2, 0x00d0, 0x10, 22, 1), + PIN_FIELD_BASE(110, 110, 2, 0x00d0, 0x10, 17, 1), + PIN_FIELD_BASE(111, 111, 2, 0x00d0, 0x10, 18, 1), + PIN_FIELD_BASE(112, 112, 2, 0x00d0, 0x10, 19, 1), + PIN_FIELD_BASE(113, 113, 2, 0x00d0, 0x10, 20, 1), + PIN_FIELD_BASE(114, 114, 2, 0x00d0, 0x10, 28, 1), + PIN_FIELD_BASE(115, 115, 2, 0x00d0, 0x10, 23, 1), + PIN_FIELD_BASE(116, 116, 2, 0x00d0, 0x10, 29, 1), + PIN_FIELD_BASE(117, 117, 2, 0x00d0, 0x10, 24, 1), + PIN_FIELD_BASE(118, 118, 2, 0x00d0, 0x10, 25, 1), + PIN_FIELD_BASE(119, 119, 2, 0x00d0, 0x10, 26, 1), + PIN_FIELD_BASE(120, 120, 2, 0x00d0, 0x10, 27, 1), + PIN_FIELD_BASE(121, 121, 3, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(122, 122, 3, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(123, 123, 3, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(124, 124, 3, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(125, 125, 2, 0x00d0, 0x10, 6, 1), + PIN_FIELD_BASE(126, 126, 2, 0x00d0, 0x10, 7, 1), + PIN_FIELD_BASE(127, 127, 2, 0x00d0, 0x10, 8, 1), + PIN_FIELD_BASE(128, 128, 2, 0x00d0, 0x10, 9, 1), + PIN_FIELD_BASE(129, 129, 2, 0x00d0, 0x10, 10, 1), + PIN_FIELD_BASE(130, 130, 2, 0x00d0, 0x10, 11, 1), + PIN_FIELD_BASE(175, 175, 2, 0x00e0, 0x10, 11, 1), + PIN_FIELD_BASE(176, 176, 2, 0x00e0, 0x10, 12, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_pd_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x00b0, 0x10, 6, 1), + PIN_FIELD_BASE(1, 1, 1, 0x00b0, 0x10, 7, 1), + PIN_FIELD_BASE(2, 2, 1, 0x00b0, 0x10, 8, 1), + PIN_FIELD_BASE(3, 3, 1, 0x00b0, 0x10, 9, 1), + PIN_FIELD_BASE(4, 4, 1, 0x00b0, 0x10, 10, 1), + PIN_FIELD_BASE(5, 5, 1, 0x00b0, 0x10, 11, 1), + PIN_FIELD_BASE(6, 6, 1, 0x00b0, 0x10, 12, 1), + PIN_FIELD_BASE(7, 7, 1, 0x00b0, 0x10, 13, 1), + PIN_FIELD_BASE(8, 8, 1, 0x00b0, 0x10, 14, 1), + PIN_FIELD_BASE(9, 9, 1, 0x00b0, 0x10, 15, 1), + PIN_FIELD_BASE(10, 10, 1, 0x00b0, 0x10, 16, 1), + PIN_FIELD_BASE(11, 11, 1, 0x00b0, 0x10, 17, 1), + PIN_FIELD_BASE(12, 12, 2, 0x00a0, 0x10, 12, 1), + PIN_FIELD_BASE(13, 13, 2, 0x00a0, 0x10, 13, 1), + PIN_FIELD_BASE(14, 14, 2, 0x00a0, 0x10, 14, 1), + PIN_FIELD_BASE(15, 15, 2, 0x00a0, 0x10, 15, 1), + PIN_FIELD_BASE(16, 16, 3, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 3, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(18, 18, 4, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(19, 19, 4, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(20, 20, 4, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(21, 21, 4, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 4, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(23, 23, 4, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(24, 24, 4, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(25, 25, 1, 0x00b0, 0x10, 3, 1), + PIN_FIELD_BASE(26, 26, 1, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(27, 27, 1, 0x00b0, 0x10, 5, 1), + PIN_FIELD_BASE(28, 28, 1, 0x00b0, 0x10, 4, 1), + PIN_FIELD_BASE(29, 29, 1, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(30, 30, 1, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(31, 31, 1, 0x00c0, 0x10, 11, 1), + PIN_FIELD_BASE(32, 32, 1, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(33, 33, 1, 0x00c0, 0x10, 13, 1), + PIN_FIELD_BASE(34, 34, 1, 0x00c0, 0x10, 12, 1), + PIN_FIELD_BASE(35, 35, 1, 0x00c0, 0x10, 15, 1), + PIN_FIELD_BASE(36, 36, 1, 0x00c0, 0x10, 14, 1), + PIN_FIELD_BASE(37, 37, 1, 0x00b0, 0x10, 21, 1), + PIN_FIELD_BASE(38, 38, 1, 0x00b0, 0x10, 18, 1), + PIN_FIELD_BASE(39, 39, 1, 0x00b0, 0x10, 19, 1), + PIN_FIELD_BASE(40, 40, 1, 0x00b0, 0x10, 20, 1), + PIN_FIELD_BASE(41, 41, 1, 0x00b0, 0x10, 22, 1), + PIN_FIELD_BASE(46, 46, 3, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(47, 47, 1, 0x00b0, 0x10, 25, 1), + PIN_FIELD_BASE(48, 48, 1, 0x00b0, 0x10, 24, 1), + PIN_FIELD_BASE(49, 49, 1, 0x00b0, 0x10, 23, 1), + PIN_FIELD_BASE(50, 50, 3, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(51, 51, 3, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(52, 52, 3, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 3, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(54, 54, 3, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(55, 55, 1, 0x00b0, 0x10, 26, 1), + PIN_FIELD_BASE(56, 56, 1, 0x00b0, 0x10, 29, 1), + PIN_FIELD_BASE(57, 57, 2, 0x00b0, 0x10, 6, 1), + PIN_FIELD_BASE(58, 58, 2, 0x00b0, 0x10, 9, 1), + PIN_FIELD_BASE(59, 59, 1, 0x00b0, 0x10, 27, 1), + PIN_FIELD_BASE(60, 60, 1, 0x00b0, 0x10, 30, 1), + PIN_FIELD_BASE(61, 61, 1, 0x00b0, 0x10, 28, 1), + PIN_FIELD_BASE(62, 62, 1, 0x00b0, 0x10, 31, 1), + PIN_FIELD_BASE(63, 63, 2, 0x00b0, 0x10, 7, 1), + PIN_FIELD_BASE(64, 64, 2, 0x00b0, 0x10, 10, 1), + PIN_FIELD_BASE(65, 65, 4, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(66, 66, 4, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(67, 67, 4, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(68, 68, 4, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(69, 69, 1, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, 1, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, 1, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(72, 72, 1, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(73, 73, 1, 0x00c0, 0x10, 2, 1), + PIN_FIELD_BASE(74, 74, 1, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(75, 75, 1, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(76, 76, 1, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(77, 77, 1, 0x00c0, 0x10, 9, 1), + PIN_FIELD_BASE(78, 78, 1, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(79, 79, 4, 0x0060, 0x10, 12, 1), + PIN_FIELD_BASE(80, 80, 4, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(81, 81, 4, 0x0060, 0x10, 14, 1), + PIN_FIELD_BASE(82, 82, 4, 0x0060, 0x10, 13, 1), + PIN_FIELD_BASE(83, 83, 2, 0x00b0, 0x10, 16, 1), + PIN_FIELD_BASE(84, 84, 2, 0x00b0, 0x10, 15, 1), + PIN_FIELD_BASE(85, 85, 2, 0x00b0, 0x10, 17, 1), + PIN_FIELD_BASE(86, 86, 2, 0x00b0, 0x10, 19, 1), + PIN_FIELD_BASE(87, 87, 2, 0x00b0, 0x10, 18, 1), + PIN_FIELD_BASE(88, 88, 2, 0x00b0, 0x10, 20, 1), + PIN_FIELD_BASE(89, 89, 2, 0x00b0, 0x10, 22, 1), + PIN_FIELD_BASE(90, 90, 2, 0x00b0, 0x10, 21, 1), + PIN_FIELD_BASE(91, 91, 2, 0x00b0, 0x10, 23, 1), + PIN_FIELD_BASE(92, 92, 2, 0x00b0, 0x10, 3, 1), + PIN_FIELD_BASE(93, 93, 2, 0x00b0, 0x10, 2, 1), + PIN_FIELD_BASE(94, 94, 2, 0x00b0, 0x10, 5, 1), + PIN_FIELD_BASE(95, 95, 2, 0x00b0, 0x10, 4, 1), + PIN_FIELD_BASE(96, 96, 2, 0x00a0, 0x10, 31, 1), + PIN_FIELD_BASE(97, 97, 2, 0x00b0, 0x10, 0, 1), + PIN_FIELD_BASE(98, 98, 2, 0x00b0, 0x10, 8, 1), + PIN_FIELD_BASE(99, 99, 2, 0x00a0, 0x10, 30, 1), + PIN_FIELD_BASE(100, 100, 2, 0x00b0, 0x10, 1, 1), + PIN_FIELD_BASE(101, 101, 2, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(102, 102, 2, 0x00a0, 0x10, 5, 1), + PIN_FIELD_BASE(103, 103, 2, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(104, 104, 2, 0x00a0, 0x10, 4, 1), + PIN_FIELD_BASE(105, 105, 2, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(106, 106, 2, 0x00a0, 0x10, 2, 1), + PIN_FIELD_BASE(107, 107, 2, 0x00a0, 0x10, 21, 1), + PIN_FIELD_BASE(108, 108, 2, 0x00a0, 0x10, 16, 1), + PIN_FIELD_BASE(109, 109, 2, 0x00a0, 0x10, 22, 1), + PIN_FIELD_BASE(110, 110, 2, 0x00a0, 0x10, 17, 1), + PIN_FIELD_BASE(111, 111, 2, 0x00a0, 0x10, 18, 1), + PIN_FIELD_BASE(112, 112, 2, 0x00a0, 0x10, 19, 1), + PIN_FIELD_BASE(113, 113, 2, 0x00a0, 0x10, 20, 1), + PIN_FIELD_BASE(114, 114, 2, 0x00a0, 0x10, 28, 1), + PIN_FIELD_BASE(115, 115, 2, 0x00a0, 0x10, 23, 1), + PIN_FIELD_BASE(116, 116, 2, 0x00a0, 0x10, 29, 1), + PIN_FIELD_BASE(117, 117, 2, 0x00a0, 0x10, 24, 1), + PIN_FIELD_BASE(118, 118, 2, 0x00a0, 0x10, 25, 1), + PIN_FIELD_BASE(119, 119, 2, 0x00a0, 0x10, 26, 1), + PIN_FIELD_BASE(120, 120, 2, 0x00a0, 0x10, 27, 1), + PIN_FIELD_BASE(121, 121, 3, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(122, 122, 3, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(123, 123, 3, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(124, 124, 3, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(125, 125, 2, 0x00a0, 0x10, 6, 1), + PIN_FIELD_BASE(126, 126, 2, 0x00a0, 0x10, 7, 1), + PIN_FIELD_BASE(127, 127, 2, 0x00a0, 0x10, 8, 1), + PIN_FIELD_BASE(128, 128, 2, 0x00a0, 0x10, 9, 1), + PIN_FIELD_BASE(129, 129, 2, 0x00a0, 0x10, 10, 1), + PIN_FIELD_BASE(130, 130, 2, 0x00a0, 0x10, 11, 1), + PIN_FIELD_BASE(175, 175, 2, 0x00b0, 0x10, 11, 1), + PIN_FIELD_BASE(176, 176, 2, 0x00b0, 0x10, 12, 1), +}; + +static const struct mtk_pin_field_calc mt8188_pin_drv_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(1, 1, 1, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(2, 2, 1, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(3, 3, 1, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(4, 4, 1, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(5, 5, 1, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(6, 6, 1, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(7, 7, 1, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(8, 8, 1, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(9, 9, 1, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(10, 10, 1, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(11, 11, 1, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(12, 12, 2, 0x0010, 0x10, 24, 3), + PIN_FIELD_BASE(13, 13, 2, 0x0010, 0x10, 27, 3), + PIN_FIELD_BASE(14, 14, 2, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(15, 15, 2, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(16, 16, 3, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(17, 17, 3, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(18, 18, 4, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(19, 19, 4, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(20, 20, 4, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(21, 21, 4, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(22, 22, 4, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(23, 23, 4, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(24, 24, 4, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(25, 25, 1, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(26, 26, 1, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(27, 27, 1, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(28, 28, 1, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(29, 29, 1, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(30, 30, 1, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(31, 31, 1, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(32, 32, 1, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(33, 33, 1, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(34, 34, 1, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(35, 35, 1, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(36, 36, 1, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(37, 37, 1, 0x0010, 0x10, 27, 3), + PIN_FIELD_BASE(38, 38, 1, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(39, 39, 1, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(40, 40, 1, 0x0010, 0x10, 24, 3), + PIN_FIELD_BASE(41, 41, 1, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(42, 42, 2, 0x0020, 0x10, 18, 3), + PIN_FIELD_BASE(43, 43, 2, 0x0020, 0x10, 18, 3), + PIN_FIELD_BASE(44, 44, 2, 0x0020, 0x10, 18, 3), + PIN_FIELD_BASE(45, 45, 2, 0x0020, 0x10, 21, 3), + PIN_FIELD_BASE(46, 46, 3, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(47, 47, 1, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(48, 48, 1, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(49, 49, 1, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(50, 50, 3, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(51, 51, 3, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(52, 52, 3, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(53, 53, 3, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(54, 54, 3, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(55, 55, 1, 0x0020, 0x10, 27, 3), + PIN_FIELD_BASE(56, 56, 1, 0x0030, 0x10, 6, 3), + PIN_FIELD_BASE(57, 57, 2, 0x0030, 0x10, 9, 3), + PIN_FIELD_BASE(58, 58, 2, 0x0030, 0x10, 15, 3), + PIN_FIELD_BASE(59, 59, 1, 0x0030, 0x10, 0, 3), + PIN_FIELD_BASE(60, 60, 1, 0x0030, 0x10, 9, 3), + PIN_FIELD_BASE(61, 61, 1, 0x0030, 0x10, 3, 3), + PIN_FIELD_BASE(62, 62, 1, 0x0030, 0x10, 12, 3), + PIN_FIELD_BASE(63, 63, 2, 0x0030, 0x10, 12, 3), + PIN_FIELD_BASE(64, 64, 2, 0x0030, 0x10, 18, 3), + PIN_FIELD_BASE(65, 65, 4, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(66, 66, 4, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(67, 67, 4, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(68, 68, 4, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(69, 69, 1, 0x0030, 0x10, 18, 3), + PIN_FIELD_BASE(70, 70, 1, 0x0030, 0x10, 15, 3), + PIN_FIELD_BASE(71, 71, 1, 0x0040, 0x10, 0, 3), + PIN_FIELD_BASE(72, 72, 1, 0x0030, 0x10, 27, 3), + PIN_FIELD_BASE(73, 73, 1, 0x0030, 0x10, 21, 3), + PIN_FIELD_BASE(74, 74, 1, 0x0030, 0x10, 24, 3), + PIN_FIELD_BASE(75, 75, 1, 0x0040, 0x10, 6, 3), + PIN_FIELD_BASE(76, 76, 1, 0x0040, 0x10, 3, 3), + PIN_FIELD_BASE(77, 77, 1, 0x0040, 0x10, 12, 3), + PIN_FIELD_BASE(78, 78, 1, 0x0040, 0x10, 9, 3), + PIN_FIELD_BASE(79, 79, 4, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(80, 80, 4, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(81, 81, 4, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(82, 82, 4, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(83, 83, 2, 0x0030, 0x10, 0, 3), + PIN_FIELD_BASE(84, 84, 2, 0x0020, 0x10, 27, 3), + PIN_FIELD_BASE(85, 85, 2, 0x0030, 0x10, 0, 3), + PIN_FIELD_BASE(86, 86, 2, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(87, 87, 2, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(88, 88, 2, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(89, 89, 2, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(90, 90, 2, 0x0030, 0x10, 0, 3), + PIN_FIELD_BASE(91, 91, 2, 0x0030, 0x10, 0, 3), + PIN_FIELD_BASE(92, 92, 2, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(93, 93, 2, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(94, 94, 2, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(95, 95, 2, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(96, 96, 2, 0x0020, 0x10, 21, 3), + PIN_FIELD_BASE(97, 97, 2, 0x0020, 0x10, 21, 3), + PIN_FIELD_BASE(98, 98, 2, 0x0020, 0x10, 24, 3), + PIN_FIELD_BASE(99, 99, 2, 0x0020, 0x10, 21, 3), + PIN_FIELD_BASE(100, 100, 2, 0x0030, 0x10, 6, 3), + PIN_FIELD_BASE(101, 101, 2, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(102, 102, 2, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(103, 103, 2, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(104, 104, 2, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(105, 105, 2, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(106, 106, 2, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(107, 107, 2, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(108, 108, 2, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(109, 109, 2, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(110, 110, 2, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(111, 111, 2, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(112, 112, 2, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(113, 113, 2, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(114, 114, 2, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(115, 115, 2, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(116, 116, 2, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(117, 117, 2, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(118, 118, 2, 0x0020, 0x10, 12, 3), + PIN_FIELD_BASE(119, 119, 2, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(120, 120, 2, 0x0020, 0x10, 18, 3), + PIN_FIELD_BASE(121, 121, 3, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(122, 122, 3, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(123, 123, 3, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(124, 124, 3, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(125, 125, 2, 0x0020, 0x10, 24, 3), + PIN_FIELD_BASE(126, 126, 2, 0x0020, 0x10, 24, 3), + PIN_FIELD_BASE(127, 127, 2, 0x0020, 0x10, 24, 3), + PIN_FIELD_BASE(128, 128, 2, 0x0020, 0x10, 27, 3), + PIN_FIELD_BASE(129, 129, 2, 0x0020, 0x10, 27, 3), + PIN_FIELD_BASE(130, 130, 2, 0x0020, 0x10, 27, 3), + PIN_FIELD_BASE(131, 131, 1, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(132, 132, 1, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(133, 133, 1, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(134, 134, 1, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(135, 135, 1, 0x0020, 0x10, 15, 3), + PIN_FIELD_BASE(136, 136, 1, 0x0020, 0x10, 18, 3), + PIN_FIELD_BASE(137, 137, 1, 0x0020, 0x10, 18, 3), + PIN_FIELD_BASE(138, 138, 1, 0x0020, 0x10, 18, 3), + PIN_FIELD_BASE(139, 139, 1, 0x0020, 0x10, 18, 3), + PIN_FIELD_BASE(140, 140, 1, 0x0020, 0x10, 21, 3), + PIN_FIELD_BASE(141, 141, 1, 0x0020, 0x10, 21, 3), + PIN_FIELD_BASE(142, 142, 1, 0x0020, 0x10, 21, 3), + PIN_FIELD_BASE(143, 143, 1, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(144, 144, 1, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(145, 145, 1, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(146, 146, 1, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(147, 147, 1, 0x0020, 0x10, 21, 3), + PIN_FIELD_BASE(148, 148, 1, 0x0020, 0x10, 24, 3), + PIN_FIELD_BASE(149, 149, 1, 0x0020, 0x10, 24, 3), + PIN_FIELD_BASE(150, 150, 1, 0x0020, 0x10, 24, 3), + PIN_FIELD_BASE(151, 151, 2, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(152, 152, 2, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(153, 153, 2, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(154, 154, 2, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(155, 155, 2, 0x0010, 0x10, 21, 3), + PIN_FIELD_BASE(156, 156, 2, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(157, 157, 2, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(158, 158, 2, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(159, 159, 2, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(160, 160, 2, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(161, 161, 2, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(162, 162, 2, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(163, 163, 4, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(164, 164, 4, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(165, 165, 4, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(166, 166, 4, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(167, 167, 4, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(168, 168, 4, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(169, 169, 3, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(170, 170, 3, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(171, 171, 3, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(172, 172, 3, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(173, 173, 3, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(174, 174, 3, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(175, 175, 2, 0x0030, 0x10, 3, 3), + PIN_FIELD_BASE(176, 176, 2, 0x0030, 0x10, 3, 3), +}; + +static const struct mtk_pin_field_calc mt8188_pin_drv_adv_range[] = { + PIN_FIELD_BASE(53, 53, 3, 0x0020, 0x10, 0, 3), + PIN_FIELD_BASE(54, 54, 3, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(55, 55, 1, 0x0060, 0x10, 0, 3), + PIN_FIELD_BASE(56, 56, 1, 0x0060, 0x10, 9, 3), + PIN_FIELD_BASE(57, 57, 2, 0x0050, 0x10, 0, 3), + PIN_FIELD_BASE(58, 58, 2, 0x0050, 0x10, 6, 3), + PIN_FIELD_BASE(59, 59, 1, 0x0060, 0x10, 3, 3), + PIN_FIELD_BASE(60, 60, 1, 0x0060, 0x10, 12, 3), + PIN_FIELD_BASE(61, 61, 1, 0x0060, 0x10, 6, 3), + PIN_FIELD_BASE(62, 62, 1, 0x0060, 0x10, 15, 3), + PIN_FIELD_BASE(63, 63, 2, 0x0050, 0x10, 3, 3), + PIN_FIELD_BASE(64, 64, 2, 0x0050, 0x10, 9, 3), + PIN_FIELD_BASE(65, 65, 4, 0x0030, 0x10, 0, 3), + PIN_FIELD_BASE(66, 66, 4, 0x0030, 0x10, 6, 3), + PIN_FIELD_BASE(67, 67, 4, 0x0030, 0x10, 3, 3), + PIN_FIELD_BASE(68, 68, 4, 0x0030, 0x10, 9, 3), + PIN_FIELD_BASE(175, 175, 2, 0x0050, 0x10, 12, 3), + PIN_FIELD_BASE(176, 176, 2, 0x0050, 0x10, 15, 3), +}; + +static const struct mtk_pin_field_calc mt8188_pin_rsel_range[] = { + PIN_FIELD_BASE(53, 53, 3, 0x00c0, 0x10, 0, 3), + PIN_FIELD_BASE(54, 54, 3, 0x00c0, 0x10, 3, 3), + PIN_FIELD_BASE(55, 55, 1, 0x0160, 0x10, 0, 3), + PIN_FIELD_BASE(56, 56, 1, 0x0160, 0x10, 9, 3), + PIN_FIELD_BASE(57, 57, 2, 0x0150, 0x10, 0, 3), + PIN_FIELD_BASE(58, 58, 2, 0x0150, 0x10, 6, 3), + PIN_FIELD_BASE(59, 59, 1, 0x0160, 0x10, 3, 3), + PIN_FIELD_BASE(60, 60, 1, 0x0160, 0x10, 12, 3), + PIN_FIELD_BASE(61, 61, 1, 0x0160, 0x10, 6, 3), + PIN_FIELD_BASE(62, 62, 1, 0x0160, 0x10, 15, 3), + PIN_FIELD_BASE(63, 63, 2, 0x0150, 0x10, 3, 3), + PIN_FIELD_BASE(64, 64, 2, 0x0150, 0x10, 9, 3), + PIN_FIELD_BASE(65, 65, 4, 0x00d0, 0x10, 0, 3), + PIN_FIELD_BASE(66, 66, 4, 0x00d0, 0x10, 6, 3), + PIN_FIELD_BASE(67, 67, 4, 0x00d0, 0x10, 3, 3), + PIN_FIELD_BASE(68, 68, 4, 0x00d0, 0x10, 9, 3), + PIN_FIELD_BASE(175, 175, 2, 0x0150, 0x10, 12, 3), + PIN_FIELD_BASE(176, 176, 2, 0x0150, 0x10, 15, 3), +}; + +static const struct mtk_pin_rsel mt8188_pin_rsel_val_range[] = { + PIN_RSEL(53, 68, 0x0, 75000, 75000), + PIN_RSEL(53, 68, 0x1, 10000, 5000), + PIN_RSEL(53, 68, 0x2, 5000, 75000), + PIN_RSEL(53, 68, 0x3, 4000, 5000), + PIN_RSEL(53, 68, 0x4, 3000, 75000), + PIN_RSEL(53, 68, 0x5, 2000, 5000), + PIN_RSEL(53, 68, 0x6, 1500, 75000), + PIN_RSEL(53, 68, 0x7, 1000, 5000), + PIN_RSEL(175, 176, 0x0, 75000, 75000), + PIN_RSEL(175, 176, 0x1, 10000, 5000), + PIN_RSEL(175, 176, 0x2, 5000, 75000), + PIN_RSEL(175, 176, 0x3, 4000, 5000), + PIN_RSEL(175, 176, 0x4, 3000, 75000), + PIN_RSEL(175, 176, 0x5, 2000, 5000), + PIN_RSEL(175, 176, 0x6, 1500, 75000), + PIN_RSEL(175, 176, 0x7, 1000, 5000), +}; + +static const unsigned int mt8188_pull_type[] = { + MTK_PULL_PU_PD_TYPE, /*0*/ + MTK_PULL_PU_PD_TYPE, /*1*/ + MTK_PULL_PU_PD_TYPE, /*2*/ + MTK_PULL_PU_PD_TYPE, /*3*/ + MTK_PULL_PU_PD_TYPE, /*4*/ + MTK_PULL_PU_PD_TYPE, /*5*/ + MTK_PULL_PU_PD_TYPE, /*6*/ + MTK_PULL_PU_PD_TYPE, /*7*/ + MTK_PULL_PU_PD_TYPE, /*8*/ + MTK_PULL_PU_PD_TYPE, /*9*/ + MTK_PULL_PU_PD_TYPE, /*10*/ + MTK_PULL_PU_PD_TYPE, /*11*/ + MTK_PULL_PU_PD_TYPE, /*12*/ + MTK_PULL_PU_PD_TYPE, /*13*/ + MTK_PULL_PU_PD_TYPE, /*14*/ + MTK_PULL_PU_PD_TYPE, /*15*/ + MTK_PULL_PU_PD_TYPE, /*16*/ + MTK_PULL_PU_PD_TYPE, /*17*/ + MTK_PULL_PU_PD_TYPE, /*18*/ + MTK_PULL_PU_PD_TYPE, /*19*/ + MTK_PULL_PU_PD_TYPE, /*20*/ + MTK_PULL_PU_PD_TYPE, /*21*/ + MTK_PULL_PU_PD_TYPE, /*22*/ + MTK_PULL_PU_PD_TYPE, /*23*/ + MTK_PULL_PU_PD_TYPE, /*24*/ + MTK_PULL_PU_PD_TYPE, /*25*/ + MTK_PULL_PU_PD_TYPE, /*26*/ + MTK_PULL_PU_PD_TYPE, /*27*/ + MTK_PULL_PU_PD_TYPE, /*28*/ + MTK_PULL_PU_PD_TYPE, /*29*/ + MTK_PULL_PU_PD_TYPE, /*30*/ + MTK_PULL_PU_PD_TYPE, /*31*/ + MTK_PULL_PU_PD_TYPE, /*32*/ + MTK_PULL_PU_PD_TYPE, /*33*/ + MTK_PULL_PU_PD_TYPE, /*34*/ + MTK_PULL_PU_PD_TYPE, /*35*/ + MTK_PULL_PU_PD_TYPE, /*36*/ + MTK_PULL_PU_PD_TYPE, /*37*/ + MTK_PULL_PU_PD_TYPE, /*38*/ + MTK_PULL_PU_PD_TYPE, /*39*/ + MTK_PULL_PU_PD_TYPE, /*40*/ + MTK_PULL_PU_PD_TYPE, /*41*/ + MTK_PULL_PUPD_R1R0_TYPE, /*42*/ + MTK_PULL_PUPD_R1R0_TYPE, /*43*/ + MTK_PULL_PUPD_R1R0_TYPE, /*44*/ + MTK_PULL_PUPD_R1R0_TYPE, /*45*/ + MTK_PULL_PU_PD_TYPE, /*46*/ + MTK_PULL_PU_PD_TYPE, /*47*/ + MTK_PULL_PU_PD_TYPE, /*48*/ + MTK_PULL_PU_PD_TYPE, /*49*/ + MTK_PULL_PU_PD_TYPE, /*50*/ + MTK_PULL_PU_PD_TYPE, /*51*/ + MTK_PULL_PU_PD_TYPE, /*52*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*53*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*54*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*55*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*56*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*57*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*58*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*59*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*60*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*61*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*62*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*63*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*64*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*65*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*66*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*67*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*68*/ + MTK_PULL_PU_PD_TYPE, /*69*/ + MTK_PULL_PU_PD_TYPE, /*70*/ + MTK_PULL_PU_PD_TYPE, /*71*/ + MTK_PULL_PU_PD_TYPE, /*72*/ + MTK_PULL_PU_PD_TYPE, /*73*/ + MTK_PULL_PU_PD_TYPE, /*74*/ + MTK_PULL_PU_PD_TYPE, /*75*/ + MTK_PULL_PU_PD_TYPE, /*76*/ + MTK_PULL_PU_PD_TYPE, /*77*/ + MTK_PULL_PU_PD_TYPE, /*78*/ + MTK_PULL_PU_PD_TYPE, /*79*/ + MTK_PULL_PU_PD_TYPE, /*80*/ + MTK_PULL_PU_PD_TYPE, /*81*/ + MTK_PULL_PU_PD_TYPE, /*82*/ + MTK_PULL_PU_PD_TYPE, /*83*/ + MTK_PULL_PU_PD_TYPE, /*84*/ + MTK_PULL_PU_PD_TYPE, /*85*/ + MTK_PULL_PU_PD_TYPE, /*86*/ + MTK_PULL_PU_PD_TYPE, /*87*/ + MTK_PULL_PU_PD_TYPE, /*88*/ + MTK_PULL_PU_PD_TYPE, /*89*/ + MTK_PULL_PU_PD_TYPE, /*90*/ + MTK_PULL_PU_PD_TYPE, /*91*/ + MTK_PULL_PU_PD_TYPE, /*92*/ + MTK_PULL_PU_PD_TYPE, /*93*/ + MTK_PULL_PU_PD_TYPE, /*94*/ + MTK_PULL_PU_PD_TYPE, /*95*/ + MTK_PULL_PU_PD_TYPE, /*96*/ + MTK_PULL_PU_PD_TYPE, /*97*/ + MTK_PULL_PU_PD_TYPE, /*98*/ + MTK_PULL_PU_PD_TYPE, /*99*/ + MTK_PULL_PU_PD_TYPE, /*100*/ + MTK_PULL_PU_PD_TYPE, /*101*/ + MTK_PULL_PU_PD_TYPE, /*102*/ + MTK_PULL_PU_PD_TYPE, /*103*/ + MTK_PULL_PU_PD_TYPE, /*104*/ + MTK_PULL_PU_PD_TYPE, /*105*/ + MTK_PULL_PU_PD_TYPE, /*106*/ + MTK_PULL_PU_PD_TYPE, /*107*/ + MTK_PULL_PU_PD_TYPE, /*108*/ + MTK_PULL_PU_PD_TYPE, /*109*/ + MTK_PULL_PU_PD_TYPE, /*110*/ + MTK_PULL_PU_PD_TYPE, /*111*/ + MTK_PULL_PU_PD_TYPE, /*112*/ + MTK_PULL_PU_PD_TYPE, /*113*/ + MTK_PULL_PU_PD_TYPE, /*114*/ + MTK_PULL_PU_PD_TYPE, /*115*/ + MTK_PULL_PU_PD_TYPE, /*116*/ + MTK_PULL_PU_PD_TYPE, /*117*/ + MTK_PULL_PU_PD_TYPE, /*118*/ + MTK_PULL_PU_PD_TYPE, /*119*/ + MTK_PULL_PU_PD_TYPE, /*120*/ + MTK_PULL_PU_PD_TYPE, /*121*/ + MTK_PULL_PU_PD_TYPE, /*122*/ + MTK_PULL_PU_PD_TYPE, /*123*/ + MTK_PULL_PU_PD_TYPE, /*124*/ + MTK_PULL_PU_PD_TYPE, /*125*/ + MTK_PULL_PU_PD_TYPE, /*126*/ + MTK_PULL_PU_PD_TYPE, /*127*/ + MTK_PULL_PU_PD_TYPE, /*128*/ + MTK_PULL_PU_PD_TYPE, /*129*/ + MTK_PULL_PU_PD_TYPE, /*130*/ + MTK_PULL_PUPD_R1R0_TYPE, /*131*/ + MTK_PULL_PUPD_R1R0_TYPE, /*132*/ + MTK_PULL_PUPD_R1R0_TYPE, /*133*/ + MTK_PULL_PUPD_R1R0_TYPE, /*134*/ + MTK_PULL_PUPD_R1R0_TYPE, /*135*/ + MTK_PULL_PUPD_R1R0_TYPE, /*136*/ + MTK_PULL_PUPD_R1R0_TYPE, /*137*/ + MTK_PULL_PUPD_R1R0_TYPE, /*138*/ + MTK_PULL_PUPD_R1R0_TYPE, /*139*/ + MTK_PULL_PUPD_R1R0_TYPE, /*140*/ + MTK_PULL_PUPD_R1R0_TYPE, /*141*/ + MTK_PULL_PUPD_R1R0_TYPE, /*142*/ + MTK_PULL_PUPD_R1R0_TYPE, /*143*/ + MTK_PULL_PUPD_R1R0_TYPE, /*144*/ + MTK_PULL_PUPD_R1R0_TYPE, /*145*/ + MTK_PULL_PUPD_R1R0_TYPE, /*146*/ + MTK_PULL_PUPD_R1R0_TYPE, /*147*/ + MTK_PULL_PUPD_R1R0_TYPE, /*148*/ + MTK_PULL_PUPD_R1R0_TYPE, /*149*/ + MTK_PULL_PUPD_R1R0_TYPE, /*150*/ + MTK_PULL_PUPD_R1R0_TYPE, /*151*/ + MTK_PULL_PUPD_R1R0_TYPE, /*152*/ + MTK_PULL_PUPD_R1R0_TYPE, /*153*/ + MTK_PULL_PUPD_R1R0_TYPE, /*154*/ + MTK_PULL_PUPD_R1R0_TYPE, /*155*/ + MTK_PULL_PUPD_R1R0_TYPE, /*156*/ + MTK_PULL_PUPD_R1R0_TYPE, /*157*/ + MTK_PULL_PUPD_R1R0_TYPE, /*158*/ + MTK_PULL_PUPD_R1R0_TYPE, /*159*/ + MTK_PULL_PUPD_R1R0_TYPE, /*160*/ + MTK_PULL_PUPD_R1R0_TYPE, /*161*/ + MTK_PULL_PUPD_R1R0_TYPE, /*162*/ + MTK_PULL_PUPD_R1R0_TYPE, /*163*/ + MTK_PULL_PUPD_R1R0_TYPE, /*164*/ + MTK_PULL_PUPD_R1R0_TYPE, /*165*/ + MTK_PULL_PUPD_R1R0_TYPE, /*166*/ + MTK_PULL_PUPD_R1R0_TYPE, /*167*/ + MTK_PULL_PUPD_R1R0_TYPE, /*168*/ + MTK_PULL_PUPD_R1R0_TYPE, /*169*/ + MTK_PULL_PUPD_R1R0_TYPE, /*170*/ + MTK_PULL_PUPD_R1R0_TYPE, /*171*/ + MTK_PULL_PUPD_R1R0_TYPE, /*172*/ + MTK_PULL_PUPD_R1R0_TYPE, /*173*/ + MTK_PULL_PUPD_R1R0_TYPE, /*174*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*175*/ + MTK_PULL_PU_PD_RSEL_TYPE, /*176*/ +}; + +static const struct mtk_pin_reg_calc mt8188_reg_cals[PINCTRL_PIN_REG_MAX] = { + [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8188_pin_mode_range), + [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8188_pin_dir_range), + [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8188_pin_di_range), + [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8188_pin_do_range), + [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8188_pin_smt_range), + [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8188_pin_ies_range), + [PINCTRL_PIN_REG_TDSEL] = MTK_RANGE(mt8188_pin_tdsel_range), + [PINCTRL_PIN_REG_RDSEL] = MTK_RANGE(mt8188_pin_rdsel_range), + [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt8188_pin_pupd_range), + [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8188_pin_r0_range), + [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8188_pin_r1_range), + [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8188_pin_pu_range), + [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt8188_pin_pd_range), + [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt8188_pin_drv_range), + [PINCTRL_PIN_REG_DRV_ADV] = MTK_RANGE(mt8188_pin_drv_adv_range), + [PINCTRL_PIN_REG_RSEL] = MTK_RANGE(mt8188_pin_rsel_range), +}; + +static const char * const mt8188_pinctrl_register_base_name[] = { + "iocfg0", "iocfg_rm", "iocfg_lt", "iocfg_lm", "iocfg_rt", +}; + +static const struct mtk_eint_hw mt8188_eint_hw = { + .port_mask = 0xf, + .ports = 7, + .ap_num = 225, + .db_cnt = 32, +}; + +static const struct mtk_pin_soc mt8188_data = { + .reg_cal = mt8188_reg_cals, + .pins = mtk_pins_mt8188, + .npins = ARRAY_SIZE(mtk_pins_mt8188), + .ngrps = ARRAY_SIZE(mtk_pins_mt8188), + .eint_hw = &mt8188_eint_hw, + .nfuncs = 8, + .gpio_m = 0, + .base_names = mt8188_pinctrl_register_base_name, + .nbase_names = ARRAY_SIZE(mt8188_pinctrl_register_base_name), + .pull_type = mt8188_pull_type, + .pin_rsel = mt8188_pin_rsel_val_range, + .npin_rsel = ARRAY_SIZE(mt8188_pin_rsel_val_range), + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, + .drive_set = mtk_pinconf_drive_set_rev1, + .drive_get = mtk_pinconf_drive_get_rev1, + .adv_drive_set = mtk_pinconf_adv_drive_set_raw, + .adv_drive_get = mtk_pinconf_adv_drive_get_raw, +}; + +static const struct of_device_id mt8188_pinctrl_of_match[] = { + { .compatible = "mediatek,mt8188-pinctrl", .data = &mt8188_data }, + { } +}; + +static struct platform_driver mt8188_pinctrl_driver = { + .driver = { + .name = "mt8188-pinctrl", + .of_match_table = mt8188_pinctrl_of_match, + .pm = &mtk_paris_pinctrl_pm_ops + }, + .probe = mtk_paris_pinctrl_probe, +}; + +static int __init mt8188_pinctrl_init(void) +{ + return platform_driver_register(&mt8188_pinctrl_driver); +} + +arch_initcall(mt8188_pinctrl_init); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek MT8188 Pinctrl Driver"); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8188.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8188.h new file mode 100644 index 000000000000..a487323748e2 --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8188.h @@ -0,0 +1,2259 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Hui Liu + * + */ + +#ifndef __PINCTRL_MTK_MT8188_H +#define __PINCTRL_MTK_MT8188_H + +#include "pinctrl-paris.h" + +static const struct mtk_pin_desc mtk_pins_mt8188[] = { + MTK_PIN( + 0, "GPIO0", + MTK_EINT_FUNCTION(0, 0), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO0"), + MTK_FUNCTION(1, "B0_TP_GPIO0_AO"), + MTK_FUNCTION(2, "O_SPIM5_CSB"), + MTK_FUNCTION(3, "O_UTXD1"), + MTK_FUNCTION(4, "O_DMIC3_CLK"), + MTK_FUNCTION(5, "B0_I2SIN_MCK"), + MTK_FUNCTION(6, "O_I2SO2_MCK"), + MTK_FUNCTION(7, "B0_DBG_MON_A0") + ), + + MTK_PIN( + 1, "GPIO1", + MTK_EINT_FUNCTION(0, 1), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO1"), + MTK_FUNCTION(1, "B0_TP_GPIO1_AO"), + MTK_FUNCTION(2, "O_SPIM5_CLK"), + MTK_FUNCTION(3, "I1_URXD1"), + MTK_FUNCTION(4, "I0_DMIC3_DAT"), + MTK_FUNCTION(5, "B0_I2SIN_BCK"), + MTK_FUNCTION(6, "B0_I2SO2_BCK"), + MTK_FUNCTION(7, "B0_DBG_MON_A1") + ), + + MTK_PIN( + 2, "GPIO2", + MTK_EINT_FUNCTION(0, 2), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO2"), + MTK_FUNCTION(1, "B0_TP_GPIO2_AO"), + MTK_FUNCTION(2, "B0_SPIM5_MOSI"), + MTK_FUNCTION(3, "O_URTS1"), + MTK_FUNCTION(4, "I0_DMIC3_DAT_R"), + MTK_FUNCTION(5, "B0_I2SIN_WS"), + MTK_FUNCTION(6, "B0_I2SO2_WS"), + MTK_FUNCTION(7, "B0_DBG_MON_A2") + ), + + MTK_PIN( + 3, "GPIO3", + MTK_EINT_FUNCTION(0, 3), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO3"), + MTK_FUNCTION(1, "B0_TP_GPIO3_AO"), + MTK_FUNCTION(2, "B0_SPIM5_MISO"), + MTK_FUNCTION(3, "I1_UCTS1"), + MTK_FUNCTION(4, "O_DMIC4_CLK"), + MTK_FUNCTION(5, "I0_I2SIN_D0"), + MTK_FUNCTION(6, "O_I2SO2_D0"), + MTK_FUNCTION(7, "B0_DBG_MON_A3") + ), + + MTK_PIN( + 4, "GPIO4", + MTK_EINT_FUNCTION(0, 4), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO4"), + MTK_FUNCTION(1, "B0_TP_GPIO4_AO"), + MTK_FUNCTION(2, "I0_SPDIF_IN2"), + MTK_FUNCTION(3, "O_I2SO1_MCK"), + MTK_FUNCTION(4, "I0_DMIC4_DAT"), + MTK_FUNCTION(5, "I0_I2SIN_D1"), + MTK_FUNCTION(6, "O_I2SO2_D1"), + MTK_FUNCTION(7, "B0_DBG_MON_A4") + ), + + MTK_PIN( + 5, "GPIO5", + MTK_EINT_FUNCTION(0, 5), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO5"), + MTK_FUNCTION(1, "B0_TP_GPIO5_AO"), + MTK_FUNCTION(2, "I0_SPDIF_IN1"), + MTK_FUNCTION(3, "O_I2SO1_BCK"), + MTK_FUNCTION(4, "I0_DMIC4_DAT_R"), + MTK_FUNCTION(5, "I0_I2SIN_D2"), + MTK_FUNCTION(6, "O_I2SO2_D2"), + MTK_FUNCTION(7, "B0_DBG_MON_A5") + ), + + MTK_PIN( + 6, "GPIO6", + MTK_EINT_FUNCTION(0, 6), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO6"), + MTK_FUNCTION(1, "B0_TP_GPIO6_AO"), + MTK_FUNCTION(2, "I0_SPDIF_IN0"), + MTK_FUNCTION(3, "O_I2SO1_WS"), + MTK_FUNCTION(4, "O_DMIC1_CLK"), + MTK_FUNCTION(5, "I0_I2SIN_D3"), + MTK_FUNCTION(6, "O_I2SO2_D3"), + MTK_FUNCTION(7, "B0_MD32_0_GPIO0") + ), + + MTK_PIN( + 7, "GPIO7", + MTK_EINT_FUNCTION(0, 7), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO7"), + MTK_FUNCTION(1, "B0_TP_GPIO7_AO"), + MTK_FUNCTION(2, "O_SPIM3_CSB"), + MTK_FUNCTION(3, "B0_TDMIN_MCK"), + MTK_FUNCTION(4, "I0_DMIC1_DAT"), + MTK_FUNCTION(5, "O_CMVREF0"), + MTK_FUNCTION(6, "O_CLKM0"), + MTK_FUNCTION(7, "B0_DBG_MON_A6") + ), + + MTK_PIN( + 8, "GPIO8", + MTK_EINT_FUNCTION(0, 8), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO8"), + MTK_FUNCTION(1, "B0_TP_GPIO0_AO"), + MTK_FUNCTION(2, "O_SPIM3_CLK"), + MTK_FUNCTION(3, "B0_TDMIN_BCK"), + MTK_FUNCTION(4, "I0_DMIC1_DAT_R"), + MTK_FUNCTION(5, "O_CMVREF1"), + MTK_FUNCTION(6, "O_CLKM1"), + MTK_FUNCTION(7, "B0_DBG_MON_A7") + ), + + MTK_PIN( + 9, "GPIO9", + MTK_EINT_FUNCTION(0, 9), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO9"), + MTK_FUNCTION(1, "B0_TP_GPIO1_AO"), + MTK_FUNCTION(2, "B0_SPIM3_MOSI"), + MTK_FUNCTION(3, "B0_TDMIN_LRCK"), + MTK_FUNCTION(4, "O_DMIC2_CLK"), + MTK_FUNCTION(5, "O_CMFLASH0"), + MTK_FUNCTION(6, "O_PWM_0"), + MTK_FUNCTION(7, "B0_DBG_MON_A8") + ), + + MTK_PIN( + 10, "GPIO10", + MTK_EINT_FUNCTION(0, 10), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO10"), + MTK_FUNCTION(1, "B0_TP_GPIO2_AO"), + MTK_FUNCTION(2, "B0_SPIM3_MISO"), + MTK_FUNCTION(3, "I0_TDMIN_DI"), + MTK_FUNCTION(4, "I0_DMIC2_DAT"), + MTK_FUNCTION(5, "O_CMFLASH1"), + MTK_FUNCTION(6, "O_PWM_1"), + MTK_FUNCTION(7, "B0_DBG_MON_A9") + ), + + MTK_PIN( + 11, "GPIO11", + MTK_EINT_FUNCTION(0, 11), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO11"), + MTK_FUNCTION(1, "B0_TP_GPIO3_AO"), + MTK_FUNCTION(2, "O_SPDIF_OUT"), + MTK_FUNCTION(3, "O_I2SO1_D0"), + MTK_FUNCTION(4, "I0_DMIC2_DAT_R"), + MTK_FUNCTION(5, "I0_DVFSRC_EXT_REQ"), + MTK_FUNCTION(6, "O_CMVREF6"), + MTK_FUNCTION(7, "B0_DBG_MON_A10") + ), + + MTK_PIN( + 12, "GPIO12", + MTK_EINT_FUNCTION(0, 12), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO12"), + MTK_FUNCTION(1, "B0_TP_GPIO4_AO"), + MTK_FUNCTION(2, "O_SPIM4_CSB"), + MTK_FUNCTION(3, "B1_JTMS_SEL3"), + MTK_FUNCTION(4, "B1_APU_JTAG_TMS"), + MTK_FUNCTION(5, "I0_VPU_UDI_TMS"), + MTK_FUNCTION(6, "I0_IPU_JTAG_TMS"), + MTK_FUNCTION(7, "I0_HDMITX20_HTPLG") + ), + + MTK_PIN( + 13, "GPIO13", + MTK_EINT_FUNCTION(0, 13), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO13"), + MTK_FUNCTION(1, "B0_TP_GPIO5_AO"), + MTK_FUNCTION(2, "O_SPIM4_CLK"), + MTK_FUNCTION(3, "I0_JTCK_SEL3"), + MTK_FUNCTION(4, "I0_APU_JTAG_TCK"), + MTK_FUNCTION(5, "I0_VPU_UDI_TCK"), + MTK_FUNCTION(6, "I0_IPU_JTAG_TCK"), + MTK_FUNCTION(7, "B1_HDMITX20_CEC") + ), + + MTK_PIN( + 14, "GPIO14", + MTK_EINT_FUNCTION(0, 14), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO14"), + MTK_FUNCTION(1, "B0_TP_GPIO6_AO"), + MTK_FUNCTION(2, "B0_SPIM4_MOSI"), + MTK_FUNCTION(3, "I1_JTDI_SEL3"), + MTK_FUNCTION(4, "I1_APU_JTAG_TDI"), + MTK_FUNCTION(5, "I0_VPU_UDI_TDI"), + MTK_FUNCTION(6, "I0_IPU_JTAG_TDI"), + MTK_FUNCTION(7, "B1_HDMITX20_SCL") + ), + + MTK_PIN( + 15, "GPIO15", + MTK_EINT_FUNCTION(0, 15), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO15"), + MTK_FUNCTION(1, "B0_TP_GPIO7_AO"), + MTK_FUNCTION(2, "B0_SPIM4_MISO"), + MTK_FUNCTION(3, "O_JTDO_SEL3"), + MTK_FUNCTION(4, "O_APU_JTAG_TDO"), + MTK_FUNCTION(5, "O_VPU_UDI_TDO"), + MTK_FUNCTION(6, "O_IPU_JTAG_TDO"), + MTK_FUNCTION(7, "B1_HDMITX20_SDA") + ), + + MTK_PIN( + 16, "GPIO16", + MTK_EINT_FUNCTION(0, 16), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO16"), + MTK_FUNCTION(1, "B0_TP_GPIO0_AO"), + MTK_FUNCTION(2, "O_UTXD3"), + MTK_FUNCTION(3, "I1_JTRSTn_SEL3"), + MTK_FUNCTION(4, "I0_APU_JTAG_TRST"), + MTK_FUNCTION(5, "I0_VPU_UDI_NTRST"), + MTK_FUNCTION(6, "I0_IPU_JTAG_TRST"), + MTK_FUNCTION(7, "O_HDMITX20_PWR5V") + ), + + MTK_PIN( + 17, "GPIO17", + MTK_EINT_FUNCTION(0, 17), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO17"), + MTK_FUNCTION(1, "B0_TP_GPIO1_AO"), + MTK_FUNCTION(2, "I1_URXD3"), + MTK_FUNCTION(3, "O_CMFLASH2"), + MTK_FUNCTION(4, "I0_EDP_TX_HPD"), + MTK_FUNCTION(5, "I0_DVFSRC_EXT_REQ"), + MTK_FUNCTION(6, "O_CMVREF7"), + MTK_FUNCTION(7, "B0_MD32_0_GPIO1") + ), + + MTK_PIN( + 18, "GPIO18", + MTK_EINT_FUNCTION(0, 18), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO18"), + MTK_FUNCTION(1, "B0_TP_GPIO2_AO"), + MTK_FUNCTION(2, "O_CMFLASH0"), + MTK_FUNCTION(3, "O_CMVREF4"), + MTK_FUNCTION(4, "B0_TDMIN_MCK"), + MTK_FUNCTION(5, "O_UTXD1"), + MTK_FUNCTION(6, "O_TP_UTXD1_AO"), + MTK_FUNCTION(7, "B0_DBG_MON_A11") + ), + + MTK_PIN( + 19, "GPIO19", + MTK_EINT_FUNCTION(0, 19), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO19"), + MTK_FUNCTION(1, "B0_TP_GPIO3_AO"), + MTK_FUNCTION(2, "O_CMFLASH1"), + MTK_FUNCTION(3, "O_CMVREF5"), + MTK_FUNCTION(4, "B0_TDMIN_BCK"), + MTK_FUNCTION(5, "I1_URXD1"), + MTK_FUNCTION(6, "I1_TP_URXD1_AO"), + MTK_FUNCTION(7, "B0_DBG_MON_A12") + ), + + MTK_PIN( + 20, "GPIO20", + MTK_EINT_FUNCTION(0, 20), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO20"), + MTK_FUNCTION(1, "B0_TP_GPIO4_AO"), + MTK_FUNCTION(2, "O_CMFLASH2"), + MTK_FUNCTION(3, "O_CLKM2"), + MTK_FUNCTION(4, "B0_TDMIN_LRCK"), + MTK_FUNCTION(5, "O_URTS1"), + MTK_FUNCTION(6, "O_TP_URTS1_AO"), + MTK_FUNCTION(7, "B0_DBG_MON_A13") + ), + + MTK_PIN( + 21, "GPIO21", + MTK_EINT_FUNCTION(0, 21), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO21"), + MTK_FUNCTION(1, "B0_TP_GPIO5_AO"), + MTK_FUNCTION(2, "O_CMFLASH3"), + MTK_FUNCTION(3, "O_CLKM3"), + MTK_FUNCTION(4, "I0_TDMIN_DI"), + MTK_FUNCTION(5, "I1_UCTS1"), + MTK_FUNCTION(6, "I1_TP_UCTS1_AO"), + MTK_FUNCTION(7, "B0_DBG_MON_A14") + ), + + MTK_PIN( + 22, "GPIO22", + MTK_EINT_FUNCTION(0, 22), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO22"), + MTK_FUNCTION(1, "O_CMMCLK0"), + MTK_FUNCTION(5, "B0_TP_GPIO6_AO"), + MTK_FUNCTION(7, "B0_DBG_MON_A15") + ), + + MTK_PIN( + 23, "GPIO23", + MTK_EINT_FUNCTION(0, 23), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO23"), + MTK_FUNCTION(1, "O_CMMCLK1"), + MTK_FUNCTION(3, "O_PWM_2"), + MTK_FUNCTION(4, "B1_PCIE_PHY_I2C_SCL"), + MTK_FUNCTION(5, "B0_TP_GPIO7_AO"), + MTK_FUNCTION(6, "I0_DP_TX_HPD"), + MTK_FUNCTION(7, "B0_DBG_MON_A16") + ), + + MTK_PIN( + 24, "GPIO24", + MTK_EINT_FUNCTION(0, 24), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO24"), + MTK_FUNCTION(1, "O_CMMCLK2"), + MTK_FUNCTION(3, "O_PWM_3"), + MTK_FUNCTION(4, "B1_PCIE_PHY_I2C_SDA"), + MTK_FUNCTION(5, "I0_DVFSRC_EXT_REQ"), + MTK_FUNCTION(6, "I0_EDP_TX_HPD"), + MTK_FUNCTION(7, "B0_MD32_0_GPIO2") + ), + + MTK_PIN( + 25, "GPIO25", + MTK_EINT_FUNCTION(0, 25), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO25"), + MTK_FUNCTION(1, "O_LCM_RST"), + MTK_FUNCTION(2, "O_LCM1_RST"), + MTK_FUNCTION(3, "I0_DP_TX_HPD") + ), + + MTK_PIN( + 26, "GPIO26", + MTK_EINT_FUNCTION(0, 26), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO26"), + MTK_FUNCTION(1, "I0_DSI_TE"), + MTK_FUNCTION(2, "I0_DSI1_TE"), + MTK_FUNCTION(3, "I0_EDP_TX_HPD") + ), + + MTK_PIN( + 27, "GPIO27", + MTK_EINT_FUNCTION(0, 27), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO27"), + MTK_FUNCTION(1, "O_LCM1_RST"), + MTK_FUNCTION(2, "O_LCM_RST"), + MTK_FUNCTION(3, "I0_DP_TX_HPD"), + MTK_FUNCTION(4, "O_CMVREF2"), + MTK_FUNCTION(5, "O_mbistwriteen_trigger"), + MTK_FUNCTION(6, "O_PWM_2"), + MTK_FUNCTION(7, "B0_DBG_MON_A17") + ), + + MTK_PIN( + 28, "GPIO28", + MTK_EINT_FUNCTION(0, 28), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO28"), + MTK_FUNCTION(1, "I0_DSI1_TE"), + MTK_FUNCTION(2, "I0_DSI_TE"), + MTK_FUNCTION(3, "I0_EDP_TX_HPD"), + MTK_FUNCTION(4, "O_CMVREF3"), + MTK_FUNCTION(5, "O_mbistreaden_trigger"), + MTK_FUNCTION(6, "O_PWM_3"), + MTK_FUNCTION(7, "B0_DBG_MON_A18") + ), + + MTK_PIN( + 29, "GPIO29", + MTK_EINT_FUNCTION(0, 29), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO29"), + MTK_FUNCTION(1, "O_DISP_PWM0"), + MTK_FUNCTION(2, "O_DISP_PWM1") + ), + + MTK_PIN( + 30, "GPIO30", + MTK_EINT_FUNCTION(0, 30), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO30"), + MTK_FUNCTION(1, "O_DISP_PWM1"), + MTK_FUNCTION(2, "O_DISP_PWM0"), + MTK_FUNCTION(3, "O_CMFLASH3"), + MTK_FUNCTION(4, "O_PWM_1"), + MTK_FUNCTION(7, "B0_DBG_MON_A19") + ), + + MTK_PIN( + 31, "GPIO31", + MTK_EINT_FUNCTION(0, 31), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO31"), + MTK_FUNCTION(1, "O_UTXD0"), + MTK_FUNCTION(2, "O_TP_UTXD1_AO"), + MTK_FUNCTION(3, "O_ADSP_UTXD0"), + MTK_FUNCTION(4, "O_TP_UTXD2_AO"), + MTK_FUNCTION(5, "O_MD32_0_TXD"), + MTK_FUNCTION(6, "O_MD32_1_TXD"), + MTK_FUNCTION(7, "O_SSPM_UTXD_AO") + ), + + MTK_PIN( + 32, "GPIO32", + MTK_EINT_FUNCTION(0, 32), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO32"), + MTK_FUNCTION(1, "I1_URXD0"), + MTK_FUNCTION(2, "I1_TP_URXD1_AO"), + MTK_FUNCTION(3, "I1_ADSP_URXD0"), + MTK_FUNCTION(4, "I1_TP_URXD2_AO"), + MTK_FUNCTION(5, "I1_MD32_0_RXD"), + MTK_FUNCTION(6, "I1_MD32_1_RXD"), + MTK_FUNCTION(7, "I1_SSPM_URXD_AO") + ), + + MTK_PIN( + 33, "GPIO33", + MTK_EINT_FUNCTION(0, 33), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO33"), + MTK_FUNCTION(1, "O_UTXD1"), + MTK_FUNCTION(2, "O_URTS2"), + MTK_FUNCTION(3, "O_ADSP_UTXD0"), + MTK_FUNCTION(4, "O_TP_UTXD1_AO"), + MTK_FUNCTION(5, "O_mbistwriteen_trigger"), + MTK_FUNCTION(6, "O_MD32_0_TXD"), + MTK_FUNCTION(7, "O_SSPM_UTXD_AO") + ), + + MTK_PIN( + 34, "GPIO34", + MTK_EINT_FUNCTION(0, 34), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO34"), + MTK_FUNCTION(1, "I1_URXD1"), + MTK_FUNCTION(2, "I1_UCTS2"), + MTK_FUNCTION(3, "I1_ADSP_URXD0"), + MTK_FUNCTION(4, "I1_TP_URXD1_AO"), + MTK_FUNCTION(5, "O_mbistreaden_trigger"), + MTK_FUNCTION(6, "I1_MD32_0_RXD"), + MTK_FUNCTION(7, "I1_SSPM_URXD_AO") + ), + + MTK_PIN( + 35, "GPIO35", + MTK_EINT_FUNCTION(0, 35), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO35"), + MTK_FUNCTION(1, "O_UTXD2"), + MTK_FUNCTION(2, "O_URTS1"), + MTK_FUNCTION(3, "O_ADSP_UTXD0"), + MTK_FUNCTION(4, "O_TP_URTS1_AO"), + MTK_FUNCTION(5, "O_TP_UTXD2_AO"), + MTK_FUNCTION(6, "O_MD32_1_TXD"), + MTK_FUNCTION(7, "B0_DBG_MON_A20") + ), + + MTK_PIN( + 36, "GPIO36", + MTK_EINT_FUNCTION(0, 36), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO36"), + MTK_FUNCTION(1, "I1_URXD2"), + MTK_FUNCTION(2, "I1_UCTS1"), + MTK_FUNCTION(3, "I1_ADSP_URXD0"), + MTK_FUNCTION(4, "I1_TP_UCTS1_AO"), + MTK_FUNCTION(5, "I1_TP_URXD2_AO"), + MTK_FUNCTION(6, "I1_MD32_1_RXD"), + MTK_FUNCTION(7, "B0_DBG_MON_A21") + ), + + MTK_PIN( + 37, "GPIO37", + MTK_EINT_FUNCTION(0, 37), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO37"), + MTK_FUNCTION(1, "B1_JTMS_SEL1"), + MTK_FUNCTION(2, "I0_UDI_TMS"), + MTK_FUNCTION(3, "I1_SPM_JTAG_TMS"), + MTK_FUNCTION(4, "I1_ADSP_JTAG0_TMS"), + MTK_FUNCTION(5, "I1_SCP_JTAG0_TMS"), + MTK_FUNCTION(6, "I1_CCU0_JTAG_TMS"), + MTK_FUNCTION(7, "I1_MCUPM_JTAG_TMS") + ), + + MTK_PIN( + 38, "GPIO38", + MTK_EINT_FUNCTION(0, 38), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO38"), + MTK_FUNCTION(1, "I0_JTCK_SEL1"), + MTK_FUNCTION(2, "I0_UDI_TCK"), + MTK_FUNCTION(3, "I1_SPM_JTAG_TCK"), + MTK_FUNCTION(4, "I0_ADSP_JTAG0_TCK"), + MTK_FUNCTION(5, "I1_SCP_JTAG0_TCK"), + MTK_FUNCTION(6, "I1_CCU0_JTAG_TCK"), + MTK_FUNCTION(7, "I1_MCUPM_JTAG_TCK") + ), + + MTK_PIN( + 39, "GPIO39", + MTK_EINT_FUNCTION(0, 39), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO39"), + MTK_FUNCTION(1, "I1_JTDI_SEL1"), + MTK_FUNCTION(2, "I0_UDI_TDI"), + MTK_FUNCTION(3, "I1_SPM_JTAG_TDI"), + MTK_FUNCTION(4, "I1_ADSP_JTAG0_TDI"), + MTK_FUNCTION(5, "I1_SCP_JTAG0_TDI"), + MTK_FUNCTION(6, "I1_CCU0_JTAG_TDI"), + MTK_FUNCTION(7, "I1_MCUPM_JTAG_TDI") + ), + + MTK_PIN( + 40, "GPIO40", + MTK_EINT_FUNCTION(0, 40), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO40"), + MTK_FUNCTION(1, "O_JTDO_SEL1"), + MTK_FUNCTION(2, "O_UDI_TDO"), + MTK_FUNCTION(3, "O_SPM_JTAG_TDO"), + MTK_FUNCTION(4, "O_ADSP_JTAG0_TDO"), + MTK_FUNCTION(5, "O_SCP_JTAG0_TDO"), + MTK_FUNCTION(6, "O_CCU0_JTAG_TDO"), + MTK_FUNCTION(7, "O_MCUPM_JTAG_TDO") + ), + + MTK_PIN( + 41, "GPIO41", + MTK_EINT_FUNCTION(0, 41), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO41"), + MTK_FUNCTION(1, "I1_JTRSTn_SEL1"), + MTK_FUNCTION(2, "I0_UDI_NTRST"), + MTK_FUNCTION(3, "I0_SPM_JTAG_TRSTN"), + MTK_FUNCTION(4, "I1_ADSP_JTAG0_TRSTN"), + MTK_FUNCTION(5, "I0_SCP_JTAG0_TRSTN"), + MTK_FUNCTION(6, "I1_CCU0_JTAG_TRST"), + MTK_FUNCTION(7, "I0_MCUPM_JTAG_TRSTN") + ), + + MTK_PIN( + 42, "GPIO42", + MTK_EINT_FUNCTION(0, 42), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO42"), + MTK_FUNCTION(1, "B1_KPCOL0") + ), + + MTK_PIN( + 43, "GPIO43", + MTK_EINT_FUNCTION(0, 43), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO43"), + MTK_FUNCTION(1, "B1_KPCOL1"), + MTK_FUNCTION(2, "I0_DP_TX_HPD"), + MTK_FUNCTION(3, "O_CMFLASH2"), + MTK_FUNCTION(4, "I0_DVFSRC_EXT_REQ"), + MTK_FUNCTION(7, "O_mbistwriteen_trigger") + ), + + MTK_PIN( + 44, "GPIO44", + MTK_EINT_FUNCTION(0, 44), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO44"), + MTK_FUNCTION(1, "B1_KPROW0") + ), + + MTK_PIN( + 45, "GPIO45", + MTK_EINT_FUNCTION(0, 45), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO45"), + MTK_FUNCTION(1, "B1_KPROW1"), + MTK_FUNCTION(2, "I0_EDP_TX_HPD"), + MTK_FUNCTION(3, "O_CMFLASH3"), + MTK_FUNCTION(4, "B0_I2SIN_MCK"), + MTK_FUNCTION(7, "O_mbistreaden_trigger") + ), + + MTK_PIN( + 46, "GPIO46", + MTK_EINT_FUNCTION(0, 46), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO46"), + MTK_FUNCTION(1, "I0_DP_TX_HPD"), + MTK_FUNCTION(2, "O_PWM_0"), + MTK_FUNCTION(3, "I0_VBUSVALID_2P"), + MTK_FUNCTION(7, "B0_DBG_MON_A22") + ), + + MTK_PIN( + 47, "GPIO47", + MTK_EINT_FUNCTION(0, 47), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO47"), + MTK_FUNCTION(1, "I1_WAKEN"), + MTK_FUNCTION(6, "O_GDU_TROOPS_DET0") + ), + + MTK_PIN( + 48, "GPIO48", + MTK_EINT_FUNCTION(0, 48), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO48"), + MTK_FUNCTION(1, "O_PERSTN"), + MTK_FUNCTION(6, "O_GDU_TROOPS_DET1") + ), + + MTK_PIN( + 49, "GPIO49", + MTK_EINT_FUNCTION(0, 49), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO49"), + MTK_FUNCTION(1, "B1_CLKREQN"), + MTK_FUNCTION(6, "O_GDU_TROOPS_DET2") + ), + + MTK_PIN( + 50, "GPIO50", + MTK_EINT_FUNCTION(0, 50), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO50"), + MTK_FUNCTION(1, "O_HDMITX20_PWR5V"), + MTK_FUNCTION(3, "I1_IDDIG_1P"), + MTK_FUNCTION(4, "I1_SCP_JTAG1_TMS"), + MTK_FUNCTION(5, "I1_SSPM_JTAG_TMS"), + MTK_FUNCTION(6, "I1_MD32_0_JTAG_TMS"), + MTK_FUNCTION(7, "I1_MD32_1_JTAG_TMS") + ), + + MTK_PIN( + 51, "GPIO51", + MTK_EINT_FUNCTION(0, 51), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO51"), + MTK_FUNCTION(1, "I0_HDMITX20_HTPLG"), + MTK_FUNCTION(2, "I0_EDP_TX_HPD"), + MTK_FUNCTION(3, "O_USB_DRVVBUS_1P"), + MTK_FUNCTION(4, "I1_SCP_JTAG1_TCK"), + MTK_FUNCTION(5, "I1_SSPM_JTAG_TCK"), + MTK_FUNCTION(6, "I1_MD32_0_JTAG_TCK"), + MTK_FUNCTION(7, "I1_MD32_1_JTAG_TCK") + ), + + MTK_PIN( + 52, "GPIO52", + MTK_EINT_FUNCTION(0, 52), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO52"), + MTK_FUNCTION(1, "B1_HDMITX20_CEC"), + MTK_FUNCTION(3, "I0_VBUSVALID_1P"), + MTK_FUNCTION(4, "I1_SCP_JTAG1_TDI"), + MTK_FUNCTION(5, "I1_SSPM_JTAG_TDI"), + MTK_FUNCTION(6, "I1_MD32_0_JTAG_TDI"), + MTK_FUNCTION(7, "I1_MD32_1_JTAG_TDI") + ), + + MTK_PIN( + 53, "GPIO53", + MTK_EINT_FUNCTION(0, 53), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO53"), + MTK_FUNCTION(1, "B1_HDMITX20_SCL"), + MTK_FUNCTION(3, "I1_IDDIG_2P"), + MTK_FUNCTION(4, "O_SCP_JTAG1_TDO"), + MTK_FUNCTION(5, "O_SSPM_JTAG_TDO"), + MTK_FUNCTION(6, "O_MD32_0_JTAG_TDO"), + MTK_FUNCTION(7, "O_MD32_1_JTAG_TDO") + ), + + MTK_PIN( + 54, "GPIO54", + MTK_EINT_FUNCTION(0, 54), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO54"), + MTK_FUNCTION(1, "B1_HDMITX20_SDA"), + MTK_FUNCTION(3, "O_USB_DRVVBUS_2P"), + MTK_FUNCTION(4, "I0_SCP_JTAG1_TRSTN"), + MTK_FUNCTION(5, "I0_SSPM_JTAG_TRSTN"), + MTK_FUNCTION(6, "I1_MD32_0_JTAG_TRST"), + MTK_FUNCTION(7, "I1_MD32_1_JTAG_TRST") + ), + + MTK_PIN( + 55, "GPIO55", + MTK_EINT_FUNCTION(0, 55), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO55"), + MTK_FUNCTION(1, "B1_SCL0"), + MTK_FUNCTION(2, "B1_SCP_SCL0"), + MTK_FUNCTION(3, "B1_SCP_SCL1"), + MTK_FUNCTION(4, "B1_PCIE_PHY_I2C_SCL") + ), + + MTK_PIN( + 56, "GPIO56", + MTK_EINT_FUNCTION(0, 56), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO56"), + MTK_FUNCTION(1, "B1_SDA0"), + MTK_FUNCTION(2, "B1_SCP_SDA0"), + MTK_FUNCTION(3, "B1_SCP_SDA1"), + MTK_FUNCTION(4, "B1_PCIE_PHY_I2C_SDA") + ), + + MTK_PIN( + 57, "GPIO57", + MTK_EINT_FUNCTION(0, 57), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO57"), + MTK_FUNCTION(1, "B1_SCL1") + ), + + MTK_PIN( + 58, "GPIO58", + MTK_EINT_FUNCTION(0, 58), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO58"), + MTK_FUNCTION(1, "B1_SDA1") + ), + + MTK_PIN( + 59, "GPIO59", + MTK_EINT_FUNCTION(0, 59), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO59"), + MTK_FUNCTION(1, "B1_SCL2"), + MTK_FUNCTION(2, "B1_SCP_SCL0"), + MTK_FUNCTION(3, "B1_SCP_SCL1") + ), + + MTK_PIN( + 60, "GPIO60", + MTK_EINT_FUNCTION(0, 60), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO60"), + MTK_FUNCTION(1, "B1_SDA2"), + MTK_FUNCTION(2, "B1_SCP_SDA0"), + MTK_FUNCTION(3, "B1_SCP_SDA1") + ), + + MTK_PIN( + 61, "GPIO61", + MTK_EINT_FUNCTION(0, 61), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO61"), + MTK_FUNCTION(1, "B1_SCL3"), + MTK_FUNCTION(2, "B1_SCP_SCL0"), + MTK_FUNCTION(3, "B1_SCP_SCL1"), + MTK_FUNCTION(4, "B1_PCIE_PHY_I2C_SCL") + ), + + MTK_PIN( + 62, "GPIO62", + MTK_EINT_FUNCTION(0, 62), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO62"), + MTK_FUNCTION(1, "B1_SDA3"), + MTK_FUNCTION(2, "B1_SCP_SDA0"), + MTK_FUNCTION(3, "B1_SCP_SDA1"), + MTK_FUNCTION(4, "B1_PCIE_PHY_I2C_SDA") + ), + + MTK_PIN( + 63, "GPIO63", + MTK_EINT_FUNCTION(0, 63), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO63"), + MTK_FUNCTION(1, "B1_SCL4") + ), + + MTK_PIN( + 64, "GPIO64", + MTK_EINT_FUNCTION(0, 64), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO64"), + MTK_FUNCTION(1, "B1_SDA4") + ), + + MTK_PIN( + 65, "GPIO65", + MTK_EINT_FUNCTION(0, 65), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO65"), + MTK_FUNCTION(1, "B1_SCL5"), + MTK_FUNCTION(2, "B1_SCP_SCL0"), + MTK_FUNCTION(3, "B1_SCP_SCL1") + ), + + MTK_PIN( + 66, "GPIO66", + MTK_EINT_FUNCTION(0, 66), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO66"), + MTK_FUNCTION(1, "B1_SDA5"), + MTK_FUNCTION(2, "B1_SCP_SDA0"), + MTK_FUNCTION(3, "B1_SCP_SDA1") + ), + + MTK_PIN( + 67, "GPIO67", + MTK_EINT_FUNCTION(0, 67), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO67"), + MTK_FUNCTION(1, "B1_SCL6"), + MTK_FUNCTION(2, "B1_SCP_SCL0"), + MTK_FUNCTION(3, "B1_SCP_SCL1"), + MTK_FUNCTION(4, "B1_PCIE_PHY_I2C_SCL") + ), + + MTK_PIN( + 68, "GPIO68", + MTK_EINT_FUNCTION(0, 68), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO68"), + MTK_FUNCTION(1, "B1_SDA6"), + MTK_FUNCTION(2, "B1_SCP_SDA0"), + MTK_FUNCTION(3, "B1_SCP_SDA1"), + MTK_FUNCTION(4, "B1_PCIE_PHY_I2C_SDA") + ), + + MTK_PIN( + 69, "GPIO69", + MTK_EINT_FUNCTION(0, 69), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO69"), + MTK_FUNCTION(1, "O_SPIM0_CSB"), + MTK_FUNCTION(2, "O_SCP_SPI0_CS"), + MTK_FUNCTION(3, "O_DMIC3_CLK"), + MTK_FUNCTION(4, "B0_MD32_1_GPIO0"), + MTK_FUNCTION(5, "O_CMVREF0"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP0_0"), + MTK_FUNCTION(7, "B0_DBG_MON_A23") + ), + + MTK_PIN( + 70, "GPIO70", + MTK_EINT_FUNCTION(0, 70), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO70"), + MTK_FUNCTION(1, "O_SPIM0_CLK"), + MTK_FUNCTION(2, "O_SCP_SPI0_CK"), + MTK_FUNCTION(3, "I0_DMIC3_DAT"), + MTK_FUNCTION(4, "B0_MD32_1_GPIO1"), + MTK_FUNCTION(5, "O_CMVREF1"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP0_1"), + MTK_FUNCTION(7, "B0_DBG_MON_A24") + ), + + MTK_PIN( + 71, "GPIO71", + MTK_EINT_FUNCTION(0, 71), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO71"), + MTK_FUNCTION(1, "B0_SPIM0_MOSI"), + MTK_FUNCTION(2, "O_SCP_SPI0_MO"), + MTK_FUNCTION(3, "I0_DMIC3_DAT_R"), + MTK_FUNCTION(4, "B0_MD32_1_GPIO2"), + MTK_FUNCTION(5, "O_CMVREF2"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP0_2"), + MTK_FUNCTION(7, "B0_DBG_MON_A25") + ), + + MTK_PIN( + 72, "GPIO72", + MTK_EINT_FUNCTION(0, 72), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO72"), + MTK_FUNCTION(1, "B0_SPIM0_MISO"), + MTK_FUNCTION(2, "I0_SCP_SPI0_MI"), + MTK_FUNCTION(3, "O_DMIC4_CLK"), + MTK_FUNCTION(5, "O_CMVREF3"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP1_0"), + MTK_FUNCTION(7, "B0_DBG_MON_A26") + ), + + MTK_PIN( + 73, "GPIO73", + MTK_EINT_FUNCTION(0, 73), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO73"), + MTK_FUNCTION(1, "B0_SPIM0_MIO2"), + MTK_FUNCTION(2, "O_UTXD3"), + MTK_FUNCTION(3, "I0_DMIC4_DAT"), + MTK_FUNCTION(4, "O_CLKM0"), + MTK_FUNCTION(5, "O_CMVREF4"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP1_1"), + MTK_FUNCTION(7, "B0_DBG_MON_A27") + ), + + MTK_PIN( + 74, "GPIO74", + MTK_EINT_FUNCTION(0, 74), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO74"), + MTK_FUNCTION(1, "B0_SPIM0_MIO3"), + MTK_FUNCTION(2, "I1_URXD3"), + MTK_FUNCTION(3, "I0_DMIC4_DAT_R"), + MTK_FUNCTION(4, "O_CLKM1"), + MTK_FUNCTION(5, "O_CMVREF5"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP1_2"), + MTK_FUNCTION(7, "B0_DBG_MON_A28") + ), + + MTK_PIN( + 75, "GPIO75", + MTK_EINT_FUNCTION(0, 75), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO75"), + MTK_FUNCTION(1, "O_SPIM1_CSB"), + MTK_FUNCTION(2, "O_SCP_SPI1_A_CS"), + MTK_FUNCTION(3, "B0_TDMIN_MCK"), + MTK_FUNCTION(4, "B1_SCP_SCL0"), + MTK_FUNCTION(5, "O_CMVREF6"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP2_0"), + MTK_FUNCTION(7, "B0_DBG_MON_A29") + ), + + MTK_PIN( + 76, "GPIO76", + MTK_EINT_FUNCTION(0, 76), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO76"), + MTK_FUNCTION(1, "O_SPIM1_CLK"), + MTK_FUNCTION(2, "O_SCP_SPI1_A_CK"), + MTK_FUNCTION(3, "B0_TDMIN_BCK"), + MTK_FUNCTION(4, "B1_SCP_SDA0"), + MTK_FUNCTION(5, "O_CMVREF7"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP2_1"), + MTK_FUNCTION(7, "B0_DBG_MON_A30") + ), + + MTK_PIN( + 77, "GPIO77", + MTK_EINT_FUNCTION(0, 77), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO77"), + MTK_FUNCTION(1, "B0_SPIM1_MOSI"), + MTK_FUNCTION(2, "O_SCP_SPI1_A_MO"), + MTK_FUNCTION(3, "B0_TDMIN_LRCK"), + MTK_FUNCTION(4, "B1_SCP_SCL1"), + MTK_FUNCTION(6, "O_GDU_SUM_TROOP2_2"), + MTK_FUNCTION(7, "B0_DBG_MON_A31") + ), + + MTK_PIN( + 78, "GPIO78", + MTK_EINT_FUNCTION(0, 78), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO78"), + MTK_FUNCTION(1, "B0_SPIM1_MISO"), + MTK_FUNCTION(2, "I0_SCP_SPI1_A_MI"), + MTK_FUNCTION(3, "I0_TDMIN_DI"), + MTK_FUNCTION(4, "B1_SCP_SDA1"), + MTK_FUNCTION(7, "B0_DBG_MON_A32") + ), + + MTK_PIN( + 79, "GPIO79", + MTK_EINT_FUNCTION(0, 79), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO79"), + MTK_FUNCTION(1, "O_SPIM2_CSB"), + MTK_FUNCTION(2, "O_SCP_SPI2_CS"), + MTK_FUNCTION(3, "O_I2SO1_MCK"), + MTK_FUNCTION(4, "O_UTXD2"), + MTK_FUNCTION(5, "O_TP_UTXD2_AO"), + MTK_FUNCTION(6, "B0_PCM_SYNC"), + MTK_FUNCTION(7, "B0_DBG_MON_B0") + ), + + MTK_PIN( + 80, "GPIO80", + MTK_EINT_FUNCTION(0, 80), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO80"), + MTK_FUNCTION(1, "O_SPIM2_CLK"), + MTK_FUNCTION(2, "O_SCP_SPI2_CK"), + MTK_FUNCTION(3, "O_I2SO1_BCK"), + MTK_FUNCTION(4, "I1_URXD2"), + MTK_FUNCTION(5, "I1_TP_URXD2_AO"), + MTK_FUNCTION(6, "B0_PCM_CLK"), + MTK_FUNCTION(7, "B0_DBG_MON_B1") + ), + + MTK_PIN( + 81, "GPIO81", + MTK_EINT_FUNCTION(0, 81), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO81"), + MTK_FUNCTION(1, "B0_SPIM2_MOSI"), + MTK_FUNCTION(2, "O_SCP_SPI2_MO"), + MTK_FUNCTION(3, "O_I2SO1_WS"), + MTK_FUNCTION(4, "O_URTS2"), + MTK_FUNCTION(5, "O_TP_URTS2_AO"), + MTK_FUNCTION(6, "O_PCM_DO"), + MTK_FUNCTION(7, "B0_DBG_MON_B2") + ), + + MTK_PIN( + 82, "GPIO82", + MTK_EINT_FUNCTION(0, 82), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO82"), + MTK_FUNCTION(1, "B0_SPIM2_MISO"), + MTK_FUNCTION(2, "I0_SCP_SPI2_MI"), + MTK_FUNCTION(3, "O_I2SO1_D0"), + MTK_FUNCTION(4, "I1_UCTS2"), + MTK_FUNCTION(5, "I1_TP_UCTS2_AO"), + MTK_FUNCTION(6, "I0_PCM_DI"), + MTK_FUNCTION(7, "B0_DBG_MON_B3") + ), + + MTK_PIN( + 83, "GPIO83", + MTK_EINT_FUNCTION(0, 83), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO83"), + MTK_FUNCTION(1, "I1_IDDIG") + ), + + MTK_PIN( + 84, "GPIO84", + MTK_EINT_FUNCTION(0, 84), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO84"), + MTK_FUNCTION(1, "O_USB_DRVVBUS") + ), + + MTK_PIN( + 85, "GPIO85", + MTK_EINT_FUNCTION(0, 85), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO85"), + MTK_FUNCTION(1, "I0_VBUSVALID") + ), + + MTK_PIN( + 86, "GPIO86", + MTK_EINT_FUNCTION(0, 86), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO86"), + MTK_FUNCTION(1, "I1_IDDIG_1P"), + MTK_FUNCTION(2, "O_UTXD1"), + MTK_FUNCTION(3, "O_URTS2"), + MTK_FUNCTION(4, "O_PWM_2"), + MTK_FUNCTION(5, "B0_TP_GPIO4_AO"), + MTK_FUNCTION(6, "O_AUXIF_ST0"), + MTK_FUNCTION(7, "B0_DBG_MON_B4") + ), + + MTK_PIN( + 87, "GPIO87", + MTK_EINT_FUNCTION(0, 87), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO87"), + MTK_FUNCTION(1, "O_USB_DRVVBUS_1P"), + MTK_FUNCTION(2, "I1_URXD1"), + MTK_FUNCTION(3, "I1_UCTS2"), + MTK_FUNCTION(4, "O_PWM_3"), + MTK_FUNCTION(5, "B0_TP_GPIO5_AO"), + MTK_FUNCTION(6, "O_AUXIF_CLK0"), + MTK_FUNCTION(7, "B0_DBG_MON_B5") + ), + + MTK_PIN( + 88, "GPIO88", + MTK_EINT_FUNCTION(0, 88), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO88"), + MTK_FUNCTION(1, "I0_VBUSVALID_1P"), + MTK_FUNCTION(2, "O_UTXD2"), + MTK_FUNCTION(3, "O_URTS1"), + MTK_FUNCTION(4, "O_CLKM2"), + MTK_FUNCTION(5, "B0_TP_GPIO6_AO"), + MTK_FUNCTION(6, "O_AUXIF_ST1"), + MTK_FUNCTION(7, "B0_DBG_MON_B6") + ), + + MTK_PIN( + 89, "GPIO89", + MTK_EINT_FUNCTION(0, 89), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO89"), + MTK_FUNCTION(1, "I1_IDDIG_2P"), + MTK_FUNCTION(2, "I1_URXD2"), + MTK_FUNCTION(3, "I1_UCTS1"), + MTK_FUNCTION(4, "O_CLKM3"), + MTK_FUNCTION(5, "B0_TP_GPIO7_AO"), + MTK_FUNCTION(6, "O_AUXIF_CLK1"), + MTK_FUNCTION(7, "B0_DBG_MON_B7") + ), + + MTK_PIN( + 90, "GPIO90", + MTK_EINT_FUNCTION(0, 90), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO90"), + MTK_FUNCTION(1, "O_USB_DRVVBUS_2P"), + MTK_FUNCTION(2, "O_UTXD3"), + MTK_FUNCTION(3, "O_ADSP_UTXD0"), + MTK_FUNCTION(4, "O_SSPM_UTXD_AO"), + MTK_FUNCTION(5, "O_MD32_0_TXD"), + MTK_FUNCTION(6, "O_MD32_1_TXD"), + MTK_FUNCTION(7, "B0_DBG_MON_B8") + ), + + MTK_PIN( + 91, "GPIO91", + MTK_EINT_FUNCTION(0, 91), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO91"), + MTK_FUNCTION(1, "I0_VBUSVALID_2P"), + MTK_FUNCTION(2, "I1_URXD3"), + MTK_FUNCTION(3, "I1_ADSP_URXD0"), + MTK_FUNCTION(4, "I1_SSPM_URXD_AO"), + MTK_FUNCTION(5, "I1_MD32_0_RXD"), + MTK_FUNCTION(6, "I1_MD32_1_RXD"), + MTK_FUNCTION(7, "B0_DBG_MON_B9") + ), + + MTK_PIN( + 92, "GPIO92", + MTK_EINT_FUNCTION(0, 92), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO92"), + MTK_FUNCTION(1, "O_PWRAP_SPI0_CSN") + ), + + MTK_PIN( + 93, "GPIO93", + MTK_EINT_FUNCTION(0, 93), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO93"), + MTK_FUNCTION(1, "O_PWRAP_SPI0_CK") + ), + + MTK_PIN( + 94, "GPIO94", + MTK_EINT_FUNCTION(0, 94), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO94"), + MTK_FUNCTION(1, "B0_PWRAP_SPI0_MO"), + MTK_FUNCTION(2, "B0_PWRAP_SPI0_MI") + ), + + MTK_PIN( + 95, "GPIO95", + MTK_EINT_FUNCTION(0, 95), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO95"), + MTK_FUNCTION(1, "B0_PWRAP_SPI0_MI"), + MTK_FUNCTION(2, "B0_PWRAP_SPI0_MO") + ), + + MTK_PIN( + 96, "GPIO96", + MTK_EINT_FUNCTION(0, 96), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO96"), + MTK_FUNCTION(1, "O_SRCLKENA0") + ), + + MTK_PIN( + 97, "GPIO97", + MTK_EINT_FUNCTION(0, 97), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO97"), + MTK_FUNCTION(1, "O_SRCLKENA1") + ), + + MTK_PIN( + 98, "GPIO98", + MTK_EINT_FUNCTION(0, 98), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO98"), + MTK_FUNCTION(1, "O_SCP_VREQ_VAO"), + MTK_FUNCTION(2, "I0_DVFSRC_EXT_REQ") + ), + + MTK_PIN( + 99, "GPIO99", + MTK_EINT_FUNCTION(0, 99), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO99"), + MTK_FUNCTION(1, "I0_RTC32K_CK") + ), + + MTK_PIN( + 100, "GPIO100", + MTK_EINT_FUNCTION(0, 100), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO100"), + MTK_FUNCTION(1, "O_WATCHDOG") + ), + + MTK_PIN( + 101, "GPIO101", + MTK_EINT_FUNCTION(0, 101), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO101"), + MTK_FUNCTION(1, "O_AUD_CLK_MOSI"), + MTK_FUNCTION(2, "O_I2SO1_MCK"), + MTK_FUNCTION(3, "B0_I2SIN_BCK") + ), + + MTK_PIN( + 102, "GPIO102", + MTK_EINT_FUNCTION(0, 102), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO102"), + MTK_FUNCTION(1, "O_AUD_SYNC_MOSI"), + MTK_FUNCTION(2, "O_I2SO1_BCK"), + MTK_FUNCTION(3, "B0_I2SIN_WS") + ), + + MTK_PIN( + 103, "GPIO103", + MTK_EINT_FUNCTION(0, 103), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO103"), + MTK_FUNCTION(1, "O_AUD_DAT_MOSI0"), + MTK_FUNCTION(2, "O_I2SO1_WS"), + MTK_FUNCTION(3, "I0_I2SIN_D0") + ), + + MTK_PIN( + 104, "GPIO104", + MTK_EINT_FUNCTION(0, 104), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO104"), + MTK_FUNCTION(1, "O_AUD_DAT_MOSI1"), + MTK_FUNCTION(2, "O_I2SO1_D0"), + MTK_FUNCTION(3, "I0_I2SIN_D1") + ), + + MTK_PIN( + 105, "GPIO105", + MTK_EINT_FUNCTION(0, 105), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO105"), + MTK_FUNCTION(1, "I0_AUD_DAT_MISO0"), + MTK_FUNCTION(2, "I0_VOW_DAT_MISO"), + MTK_FUNCTION(3, "I0_I2SIN_D2") + ), + + MTK_PIN( + 106, "GPIO106", + MTK_EINT_FUNCTION(0, 106), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO106"), + MTK_FUNCTION(1, "I0_AUD_DAT_MISO1"), + MTK_FUNCTION(2, "I0_VOW_CLK_MISO"), + MTK_FUNCTION(3, "I0_I2SIN_D3") + ), + + MTK_PIN( + 107, "GPIO107", + MTK_EINT_FUNCTION(0, 107), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO107"), + MTK_FUNCTION(1, "B0_I2SIN_MCK"), + MTK_FUNCTION(2, "I0_SPLIN_MCK"), + MTK_FUNCTION(3, "I0_SPDIF_IN0"), + MTK_FUNCTION(4, "O_CMVREF4"), + MTK_FUNCTION(5, "O_AUXIF_ST0"), + MTK_FUNCTION(6, "O_PGD_LV_LSC_PWR0") + ), + + MTK_PIN( + 108, "GPIO108", + MTK_EINT_FUNCTION(0, 108), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO108"), + MTK_FUNCTION(1, "B0_I2SIN_BCK"), + MTK_FUNCTION(2, "I0_SPLIN_LRCK"), + MTK_FUNCTION(3, "O_DMIC4_CLK"), + MTK_FUNCTION(4, "O_CMVREF5"), + MTK_FUNCTION(5, "O_AUXIF_CLK0"), + MTK_FUNCTION(6, "O_PGD_LV_LSC_PWR1"), + MTK_FUNCTION(7, "B0_DBG_MON_B10") + ), + + MTK_PIN( + 109, "GPIO109", + MTK_EINT_FUNCTION(0, 109), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO109"), + MTK_FUNCTION(1, "B0_I2SIN_WS"), + MTK_FUNCTION(2, "I0_SPLIN_BCK"), + MTK_FUNCTION(3, "I0_DMIC4_DAT"), + MTK_FUNCTION(4, "O_CMVREF6"), + MTK_FUNCTION(5, "O_AUXIF_ST1"), + MTK_FUNCTION(6, "O_PGD_LV_LSC_PWR2"), + MTK_FUNCTION(7, "B0_DBG_MON_B11") + ), + + MTK_PIN( + 110, "GPIO110", + MTK_EINT_FUNCTION(0, 110), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO110"), + MTK_FUNCTION(1, "I0_I2SIN_D0"), + MTK_FUNCTION(2, "I0_SPLIN_D0"), + MTK_FUNCTION(3, "I0_DMIC4_DAT_R"), + MTK_FUNCTION(4, "O_CMVREF7"), + MTK_FUNCTION(5, "O_AUXIF_CLK1"), + MTK_FUNCTION(6, "O_PGD_LV_LSC_PWR3"), + MTK_FUNCTION(7, "B0_DBG_MON_B12") + ), + + MTK_PIN( + 111, "GPIO111", + MTK_EINT_FUNCTION(0, 111), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO111"), + MTK_FUNCTION(1, "I0_I2SIN_D1"), + MTK_FUNCTION(2, "I0_SPLIN_D1"), + MTK_FUNCTION(3, "O_DMIC3_CLK"), + MTK_FUNCTION(4, "O_SPDIF_OUT"), + MTK_FUNCTION(6, "O_PGD_LV_LSC_PWR4"), + MTK_FUNCTION(7, "B0_DBG_MON_B13") + ), + + MTK_PIN( + 112, "GPIO112", + MTK_EINT_FUNCTION(0, 112), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO112"), + MTK_FUNCTION(1, "I0_I2SIN_D2"), + MTK_FUNCTION(2, "I0_SPLIN_D2"), + MTK_FUNCTION(3, "I0_DMIC3_DAT"), + MTK_FUNCTION(4, "B0_TDMIN_MCK"), + MTK_FUNCTION(5, "O_I2SO1_WS"), + MTK_FUNCTION(6, "O_PGD_LV_LSC_PWR5"), + MTK_FUNCTION(7, "B0_DBG_MON_B14") + ), + + MTK_PIN( + 113, "GPIO113", + MTK_EINT_FUNCTION(0, 113), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO113"), + MTK_FUNCTION(1, "I0_I2SIN_D3"), + MTK_FUNCTION(2, "I0_SPLIN_D3"), + MTK_FUNCTION(3, "I0_DMIC3_DAT_R"), + MTK_FUNCTION(4, "B0_TDMIN_BCK"), + MTK_FUNCTION(5, "O_I2SO1_D0"), + MTK_FUNCTION(7, "B0_DBG_MON_B15") + ), + + MTK_PIN( + 114, "GPIO114", + MTK_EINT_FUNCTION(0, 114), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO114"), + MTK_FUNCTION(1, "O_I2SO2_MCK"), + MTK_FUNCTION(2, "B0_I2SIN_MCK"), + MTK_FUNCTION(3, "I1_MCUPM_JTAG_TMS"), + MTK_FUNCTION(4, "B1_APU_JTAG_TMS"), + MTK_FUNCTION(5, "I1_SCP_JTAG1_TMS"), + MTK_FUNCTION(6, "I1_SPM_JTAG_TMS"), + MTK_FUNCTION(7, "B0_DBG_MON_B16") + ), + + MTK_PIN( + 115, "GPIO115", + MTK_EINT_FUNCTION(0, 115), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO115"), + MTK_FUNCTION(1, "B0_I2SO2_BCK"), + MTK_FUNCTION(2, "B0_I2SIN_BCK"), + MTK_FUNCTION(3, "I1_MCUPM_JTAG_TCK"), + MTK_FUNCTION(4, "I0_APU_JTAG_TCK"), + MTK_FUNCTION(5, "I1_SCP_JTAG1_TCK"), + MTK_FUNCTION(6, "I1_SPM_JTAG_TCK"), + MTK_FUNCTION(7, "B0_DBG_MON_B17") + ), + + MTK_PIN( + 116, "GPIO116", + MTK_EINT_FUNCTION(0, 116), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO116"), + MTK_FUNCTION(1, "B0_I2SO2_WS"), + MTK_FUNCTION(2, "B0_I2SIN_WS"), + MTK_FUNCTION(3, "I1_MCUPM_JTAG_TDI"), + MTK_FUNCTION(4, "I1_APU_JTAG_TDI"), + MTK_FUNCTION(5, "I1_SCP_JTAG1_TDI"), + MTK_FUNCTION(6, "I1_SPM_JTAG_TDI"), + MTK_FUNCTION(7, "B0_DBG_MON_B18") + ), + + MTK_PIN( + 117, "GPIO117", + MTK_EINT_FUNCTION(0, 117), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO117"), + MTK_FUNCTION(1, "O_I2SO2_D0"), + MTK_FUNCTION(2, "I0_I2SIN_D0"), + MTK_FUNCTION(3, "O_MCUPM_JTAG_TDO"), + MTK_FUNCTION(4, "O_APU_JTAG_TDO"), + MTK_FUNCTION(5, "O_SCP_JTAG1_TDO"), + MTK_FUNCTION(6, "O_SPM_JTAG_TDO"), + MTK_FUNCTION(7, "B0_DBG_MON_B19") + ), + + MTK_PIN( + 118, "GPIO118", + MTK_EINT_FUNCTION(0, 118), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO118"), + MTK_FUNCTION(1, "O_I2SO2_D1"), + MTK_FUNCTION(2, "I0_I2SIN_D1"), + MTK_FUNCTION(3, "I0_MCUPM_JTAG_TRSTN"), + MTK_FUNCTION(4, "I0_APU_JTAG_TRST"), + MTK_FUNCTION(5, "I0_SCP_JTAG1_TRSTN"), + MTK_FUNCTION(6, "I0_SPM_JTAG_TRSTN"), + MTK_FUNCTION(7, "B0_DBG_MON_B20") + ), + + MTK_PIN( + 119, "GPIO119", + MTK_EINT_FUNCTION(0, 119), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO119"), + MTK_FUNCTION(1, "O_I2SO2_D2"), + MTK_FUNCTION(2, "I0_I2SIN_D2"), + MTK_FUNCTION(3, "O_UTXD3"), + MTK_FUNCTION(4, "B0_TDMIN_LRCK"), + MTK_FUNCTION(5, "O_I2SO1_MCK"), + MTK_FUNCTION(6, "O_SSPM_UTXD_AO"), + MTK_FUNCTION(7, "B0_DBG_MON_B21") + ), + + MTK_PIN( + 120, "GPIO120", + MTK_EINT_FUNCTION(0, 120), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO120"), + MTK_FUNCTION(1, "O_I2SO2_D3"), + MTK_FUNCTION(2, "I0_I2SIN_D3"), + MTK_FUNCTION(3, "I1_URXD3"), + MTK_FUNCTION(4, "I0_TDMIN_DI"), + MTK_FUNCTION(5, "O_I2SO1_BCK"), + MTK_FUNCTION(6, "I1_SSPM_URXD_AO"), + MTK_FUNCTION(7, "B0_DBG_MON_B22") + ), + + MTK_PIN( + 121, "GPIO121", + MTK_EINT_FUNCTION(0, 121), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO121"), + MTK_FUNCTION(1, "B0_PCM_CLK"), + MTK_FUNCTION(2, "O_SPIM4_CSB"), + MTK_FUNCTION(3, "O_SCP_SPI1_B_CS"), + MTK_FUNCTION(4, "O_TP_UTXD2_AO"), + MTK_FUNCTION(5, "O_AUXIF_ST0"), + MTK_FUNCTION(6, "O_PGD_DA_EFUSE_RDY"), + MTK_FUNCTION(7, "B0_DBG_MON_B23") + ), + + MTK_PIN( + 122, "GPIO122", + MTK_EINT_FUNCTION(0, 122), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO122"), + MTK_FUNCTION(1, "B0_PCM_SYNC"), + MTK_FUNCTION(2, "O_SPIM4_CLK"), + MTK_FUNCTION(3, "O_SCP_SPI1_B_CK"), + MTK_FUNCTION(4, "I1_TP_URXD2_AO"), + MTK_FUNCTION(5, "O_AUXIF_CLK0"), + MTK_FUNCTION(6, "O_PGD_DA_EFUSE_RDY_PRE"), + MTK_FUNCTION(7, "B0_DBG_MON_B24") + ), + + MTK_PIN( + 123, "GPIO123", + MTK_EINT_FUNCTION(0, 123), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO123"), + MTK_FUNCTION(1, "O_PCM_DO"), + MTK_FUNCTION(2, "B0_SPIM4_MOSI"), + MTK_FUNCTION(3, "O_SCP_SPI1_B_MO"), + MTK_FUNCTION(4, "O_TP_URTS2_AO"), + MTK_FUNCTION(5, "O_AUXIF_ST1"), + MTK_FUNCTION(6, "O_PGD_DA_PWRGD_RESET"), + MTK_FUNCTION(7, "B0_DBG_MON_B25") + ), + + MTK_PIN( + 124, "GPIO124", + MTK_EINT_FUNCTION(0, 124), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO124"), + MTK_FUNCTION(1, "I0_PCM_DI"), + MTK_FUNCTION(2, "B0_SPIM4_MISO"), + MTK_FUNCTION(3, "I0_SCP_SPI1_B_MI"), + MTK_FUNCTION(4, "I1_TP_UCTS2_AO"), + MTK_FUNCTION(5, "O_AUXIF_CLK1"), + MTK_FUNCTION(6, "O_PGD_DA_PWRGD_ENB"), + MTK_FUNCTION(7, "B0_DBG_MON_B26") + ), + + MTK_PIN( + 125, "GPIO125", + MTK_EINT_FUNCTION(0, 125), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO125"), + MTK_FUNCTION(1, "O_DMIC1_CLK"), + MTK_FUNCTION(2, "O_SPINOR_CK"), + MTK_FUNCTION(3, "B0_TDMIN_MCK"), + MTK_FUNCTION(6, "O_LVTS_FOUT"), + MTK_FUNCTION(7, "B0_DBG_MON_B27") + ), + + MTK_PIN( + 126, "GPIO126", + MTK_EINT_FUNCTION(0, 126), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO126"), + MTK_FUNCTION(1, "I0_DMIC1_DAT"), + MTK_FUNCTION(2, "O_SPINOR_CS"), + MTK_FUNCTION(3, "B0_TDMIN_BCK"), + MTK_FUNCTION(6, "O_LVTS_SDO"), + MTK_FUNCTION(7, "B0_DBG_MON_B28") + ), + + MTK_PIN( + 127, "GPIO127", + MTK_EINT_FUNCTION(0, 127), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO127"), + MTK_FUNCTION(1, "I0_DMIC1_DAT_R"), + MTK_FUNCTION(2, "B0_SPINOR_IO0"), + MTK_FUNCTION(3, "B0_TDMIN_LRCK"), + MTK_FUNCTION(6, "I0_LVTS_26M"), + MTK_FUNCTION(7, "B0_DBG_MON_B29") + ), + + MTK_PIN( + 128, "GPIO128", + MTK_EINT_FUNCTION(0, 128), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO128"), + MTK_FUNCTION(1, "O_DMIC2_CLK"), + MTK_FUNCTION(2, "B0_SPINOR_IO1"), + MTK_FUNCTION(3, "I0_TDMIN_DI"), + MTK_FUNCTION(6, "I0_LVTS_SCF"), + MTK_FUNCTION(7, "B0_DBG_MON_B30") + ), + + MTK_PIN( + 129, "GPIO129", + MTK_EINT_FUNCTION(0, 129), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO129"), + MTK_FUNCTION(1, "I0_DMIC2_DAT"), + MTK_FUNCTION(2, "B0_SPINOR_IO2"), + MTK_FUNCTION(3, "I0_SPDIF_IN1"), + MTK_FUNCTION(6, "I0_LVTS_SCK"), + MTK_FUNCTION(7, "B0_DBG_MON_B31") + ), + + MTK_PIN( + 130, "GPIO130", + MTK_EINT_FUNCTION(0, 130), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO130"), + MTK_FUNCTION(1, "I0_DMIC2_DAT_R"), + MTK_FUNCTION(2, "B0_SPINOR_IO3"), + MTK_FUNCTION(3, "I0_SPDIF_IN2"), + MTK_FUNCTION(6, "I0_LVTS_SDI"), + MTK_FUNCTION(7, "B0_DBG_MON_B32") + ), + + MTK_PIN( + 131, "GPIO131", + MTK_EINT_FUNCTION(0, 131), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO131"), + MTK_FUNCTION(1, "O_DPI_D0"), + MTK_FUNCTION(2, "O_GBE_TXD3"), + MTK_FUNCTION(3, "O_DMIC1_CLK"), + MTK_FUNCTION(4, "O_I2SO2_MCK"), + MTK_FUNCTION(5, "B0_TP_GPIO0_AO"), + MTK_FUNCTION(6, "O_SPIM5_CSB"), + MTK_FUNCTION(7, "O_PGD_LV_HSC_PWR0") + ), + + MTK_PIN( + 132, "GPIO132", + MTK_EINT_FUNCTION(0, 132), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO132"), + MTK_FUNCTION(1, "O_DPI_D1"), + MTK_FUNCTION(2, "O_GBE_TXD2"), + MTK_FUNCTION(3, "I0_DMIC1_DAT"), + MTK_FUNCTION(4, "B0_I2SO2_BCK"), + MTK_FUNCTION(5, "B0_TP_GPIO1_AO"), + MTK_FUNCTION(6, "O_SPIM5_CLK"), + MTK_FUNCTION(7, "O_PGD_LV_HSC_PWR1") + ), + + MTK_PIN( + 133, "GPIO133", + MTK_EINT_FUNCTION(0, 133), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO133"), + MTK_FUNCTION(1, "O_DPI_D2"), + MTK_FUNCTION(2, "O_GBE_TXD1"), + MTK_FUNCTION(3, "I0_DMIC1_DAT_R"), + MTK_FUNCTION(4, "B0_I2SO2_WS"), + MTK_FUNCTION(5, "B0_TP_GPIO2_AO"), + MTK_FUNCTION(6, "B0_SPIM5_MOSI"), + MTK_FUNCTION(7, "O_PGD_LV_HSC_PWR2") + ), + + MTK_PIN( + 134, "GPIO134", + MTK_EINT_FUNCTION(0, 134), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO134"), + MTK_FUNCTION(1, "O_DPI_D3"), + MTK_FUNCTION(2, "O_GBE_TXD0"), + MTK_FUNCTION(3, "O_DMIC2_CLK"), + MTK_FUNCTION(4, "O_I2SO2_D0"), + MTK_FUNCTION(5, "B0_TP_GPIO3_AO"), + MTK_FUNCTION(6, "B0_SPIM5_MISO"), + MTK_FUNCTION(7, "O_PGD_LV_HSC_PWR3") + ), + + MTK_PIN( + 135, "GPIO135", + MTK_EINT_FUNCTION(0, 135), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO135"), + MTK_FUNCTION(1, "O_DPI_D4"), + MTK_FUNCTION(2, "I0_GBE_RXD3"), + MTK_FUNCTION(3, "I0_DMIC2_DAT"), + MTK_FUNCTION(4, "O_I2SO2_D1"), + MTK_FUNCTION(5, "B0_TP_GPIO4_AO"), + MTK_FUNCTION(6, "I1_WAKEN"), + MTK_FUNCTION(7, "O_PGD_LV_HSC_PWR4") + ), + + MTK_PIN( + 136, "GPIO136", + MTK_EINT_FUNCTION(0, 136), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO136"), + MTK_FUNCTION(1, "O_DPI_D5"), + MTK_FUNCTION(2, "I0_GBE_RXD2"), + MTK_FUNCTION(3, "I0_DMIC2_DAT_R"), + MTK_FUNCTION(4, "O_I2SO2_D2"), + MTK_FUNCTION(5, "B0_TP_GPIO5_AO"), + MTK_FUNCTION(6, "O_PERSTN"), + MTK_FUNCTION(7, "O_PGD_LV_HSC_PWR5") + ), + + MTK_PIN( + 137, "GPIO137", + MTK_EINT_FUNCTION(0, 137), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO137"), + MTK_FUNCTION(1, "O_DPI_D6"), + MTK_FUNCTION(2, "I0_GBE_RXD1"), + MTK_FUNCTION(3, "O_DMIC3_CLK"), + MTK_FUNCTION(4, "O_I2SO2_D3"), + MTK_FUNCTION(5, "B0_TP_GPIO6_AO"), + MTK_FUNCTION(6, "B1_CLKREQN"), + MTK_FUNCTION(7, "O_PWM_0") + ), + + MTK_PIN( + 138, "GPIO138", + MTK_EINT_FUNCTION(0, 138), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO138"), + MTK_FUNCTION(1, "O_DPI_D7"), + MTK_FUNCTION(2, "I0_GBE_RXD0"), + MTK_FUNCTION(3, "I0_DMIC3_DAT"), + MTK_FUNCTION(4, "O_CLKM2"), + MTK_FUNCTION(5, "B0_TP_GPIO7_AO"), + MTK_FUNCTION(7, "B0_MD32_0_GPIO0") + ), + + MTK_PIN( + 139, "GPIO139", + MTK_EINT_FUNCTION(0, 139), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO139"), + MTK_FUNCTION(1, "O_DPI_D8"), + MTK_FUNCTION(2, "B0_GBE_TXC"), + MTK_FUNCTION(3, "I0_DMIC3_DAT_R"), + MTK_FUNCTION(4, "O_CLKM3"), + MTK_FUNCTION(5, "O_TP_UTXD2_AO"), + MTK_FUNCTION(6, "O_UTXD2"), + MTK_FUNCTION(7, "B0_MD32_0_GPIO1") + ), + + MTK_PIN( + 140, "GPIO140", + MTK_EINT_FUNCTION(0, 140), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO140"), + MTK_FUNCTION(1, "O_DPI_D9"), + MTK_FUNCTION(2, "I0_GBE_RXC"), + MTK_FUNCTION(3, "O_DMIC4_CLK"), + MTK_FUNCTION(4, "O_PWM_2"), + MTK_FUNCTION(5, "I1_TP_URXD2_AO"), + MTK_FUNCTION(6, "I1_URXD2"), + MTK_FUNCTION(7, "B0_MD32_0_GPIO2") + ), + + MTK_PIN( + 141, "GPIO141", + MTK_EINT_FUNCTION(0, 141), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO141"), + MTK_FUNCTION(1, "O_DPI_D10"), + MTK_FUNCTION(2, "I0_GBE_RXDV"), + MTK_FUNCTION(3, "I0_DMIC4_DAT"), + MTK_FUNCTION(4, "O_PWM_3"), + MTK_FUNCTION(5, "O_TP_URTS2_AO"), + MTK_FUNCTION(6, "O_URTS2"), + MTK_FUNCTION(7, "B0_MD32_1_GPIO0") + ), + + MTK_PIN( + 142, "GPIO142", + MTK_EINT_FUNCTION(0, 142), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO142"), + MTK_FUNCTION(1, "O_DPI_D11"), + MTK_FUNCTION(2, "O_GBE_TXEN"), + MTK_FUNCTION(3, "I0_DMIC4_DAT_R"), + MTK_FUNCTION(4, "O_PWM_1"), + MTK_FUNCTION(5, "I1_TP_UCTS2_AO"), + MTK_FUNCTION(6, "I1_UCTS2"), + MTK_FUNCTION(7, "B0_MD32_1_GPIO1") + ), + + MTK_PIN( + 143, "GPIO143", + MTK_EINT_FUNCTION(0, 143), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO143"), + MTK_FUNCTION(1, "O_DPI_D12"), + MTK_FUNCTION(2, "O_GBE_MDC"), + MTK_FUNCTION(3, "B0_MD32_0_GPIO0"), + MTK_FUNCTION(4, "O_CLKM0"), + MTK_FUNCTION(5, "O_SPIM3_CSB"), + MTK_FUNCTION(6, "O_UTXD1"), + MTK_FUNCTION(7, "B0_MD32_1_GPIO2") + ), + + MTK_PIN( + 144, "GPIO144", + MTK_EINT_FUNCTION(0, 144), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO144"), + MTK_FUNCTION(1, "O_DPI_D13"), + MTK_FUNCTION(2, "B1_GBE_MDIO"), + MTK_FUNCTION(3, "B0_MD32_0_GPIO1"), + MTK_FUNCTION(4, "O_CLKM1"), + MTK_FUNCTION(5, "O_SPIM3_CLK"), + MTK_FUNCTION(6, "I1_URXD1"), + MTK_FUNCTION(7, "O_PGD_HV_HSC_PWR0") + ), + + MTK_PIN( + 145, "GPIO145", + MTK_EINT_FUNCTION(0, 145), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO145"), + MTK_FUNCTION(1, "O_DPI_D14"), + MTK_FUNCTION(2, "O_GBE_TXER"), + MTK_FUNCTION(3, "B0_MD32_1_GPIO0"), + MTK_FUNCTION(4, "O_CMFLASH0"), + MTK_FUNCTION(5, "B0_SPIM3_MOSI"), + MTK_FUNCTION(6, "B0_GBE_AUX_PPS2"), + MTK_FUNCTION(7, "O_PGD_HV_HSC_PWR1") + ), + + MTK_PIN( + 146, "GPIO146", + MTK_EINT_FUNCTION(0, 146), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO146"), + MTK_FUNCTION(1, "O_DPI_D15"), + MTK_FUNCTION(2, "I0_GBE_RXER"), + MTK_FUNCTION(3, "B0_MD32_1_GPIO1"), + MTK_FUNCTION(4, "O_CMFLASH1"), + MTK_FUNCTION(5, "B0_SPIM3_MISO"), + MTK_FUNCTION(6, "B0_GBE_AUX_PPS3"), + MTK_FUNCTION(7, "O_PGD_HV_HSC_PWR2") + ), + + MTK_PIN( + 147, "GPIO147", + MTK_EINT_FUNCTION(0, 147), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO147"), + MTK_FUNCTION(1, "O_DPI_HSYNC"), + MTK_FUNCTION(2, "I0_GBE_COL"), + MTK_FUNCTION(3, "O_I2SO1_MCK"), + MTK_FUNCTION(4, "O_CMVREF0"), + MTK_FUNCTION(5, "O_SPDIF_OUT"), + MTK_FUNCTION(6, "O_URTS1"), + MTK_FUNCTION(7, "O_PGD_HV_HSC_PWR3") + ), + + MTK_PIN( + 148, "GPIO148", + MTK_EINT_FUNCTION(0, 148), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO148"), + MTK_FUNCTION(1, "O_DPI_VSYNC"), + MTK_FUNCTION(2, "I0_GBE_INTR"), + MTK_FUNCTION(3, "O_I2SO1_BCK"), + MTK_FUNCTION(4, "O_CMVREF1"), + MTK_FUNCTION(5, "I0_SPDIF_IN0"), + MTK_FUNCTION(6, "I1_UCTS1"), + MTK_FUNCTION(7, "O_PGD_HV_HSC_PWR4") + ), + + MTK_PIN( + 149, "GPIO149", + MTK_EINT_FUNCTION(0, 149), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO149"), + MTK_FUNCTION(1, "O_DPI_DE"), + MTK_FUNCTION(2, "B0_GBE_AUX_PPS0"), + MTK_FUNCTION(3, "O_I2SO1_WS"), + MTK_FUNCTION(4, "O_CMVREF2"), + MTK_FUNCTION(5, "I0_SPDIF_IN1"), + MTK_FUNCTION(6, "O_UTXD3"), + MTK_FUNCTION(7, "O_PGD_HV_HSC_PWR5") + ), + + MTK_PIN( + 150, "GPIO150", + MTK_EINT_FUNCTION(0, 150), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO150"), + MTK_FUNCTION(1, "O_DPI_CK"), + MTK_FUNCTION(2, "B0_GBE_AUX_PPS1"), + MTK_FUNCTION(3, "O_I2SO1_D0"), + MTK_FUNCTION(4, "O_CMVREF3"), + MTK_FUNCTION(5, "I0_SPDIF_IN2"), + MTK_FUNCTION(6, "I1_URXD3") + ), + + MTK_PIN( + 151, "GPIO151", + MTK_EINT_FUNCTION(0, 151), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO151"), + MTK_FUNCTION(1, "B1_MSDC0_DAT7") + ), + + MTK_PIN( + 152, "GPIO152", + MTK_EINT_FUNCTION(0, 152), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO152"), + MTK_FUNCTION(1, "B1_MSDC0_DAT6") + ), + + MTK_PIN( + 153, "GPIO153", + MTK_EINT_FUNCTION(0, 153), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO153"), + MTK_FUNCTION(1, "B1_MSDC0_DAT5") + ), + + MTK_PIN( + 154, "GPIO154", + MTK_EINT_FUNCTION(0, 154), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO154"), + MTK_FUNCTION(1, "B1_MSDC0_DAT4") + ), + + MTK_PIN( + 155, "GPIO155", + MTK_EINT_FUNCTION(0, 155), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO155"), + MTK_FUNCTION(1, "O_MSDC0_RSTB") + ), + + MTK_PIN( + 156, "GPIO156", + MTK_EINT_FUNCTION(0, 156), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO156"), + MTK_FUNCTION(1, "B1_MSDC0_CMD") + ), + + MTK_PIN( + 157, "GPIO157", + MTK_EINT_FUNCTION(0, 157), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO157"), + MTK_FUNCTION(1, "B1_MSDC0_CLK") + ), + + MTK_PIN( + 158, "GPIO158", + MTK_EINT_FUNCTION(0, 158), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO158"), + MTK_FUNCTION(1, "B1_MSDC0_DAT3") + ), + + MTK_PIN( + 159, "GPIO159", + MTK_EINT_FUNCTION(0, 159), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO159"), + MTK_FUNCTION(1, "B1_MSDC0_DAT2") + ), + + MTK_PIN( + 160, "GPIO160", + MTK_EINT_FUNCTION(0, 160), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO160"), + MTK_FUNCTION(1, "B1_MSDC0_DAT1") + ), + + MTK_PIN( + 161, "GPIO161", + MTK_EINT_FUNCTION(0, 161), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO161"), + MTK_FUNCTION(1, "B1_MSDC0_DAT0") + ), + + MTK_PIN( + 162, "GPIO162", + MTK_EINT_FUNCTION(0, 162), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO162"), + MTK_FUNCTION(1, "B0_MSDC0_DSL") + ), + + MTK_PIN( + 163, "GPIO163", + MTK_EINT_FUNCTION(0, 163), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO163"), + MTK_FUNCTION(1, "B1_MSDC1_CMD"), + MTK_FUNCTION(2, "O_SPDIF_OUT"), + MTK_FUNCTION(3, "I1_MD32_0_JTAG_TMS"), + MTK_FUNCTION(4, "I1_ADSP_JTAG0_TMS"), + MTK_FUNCTION(5, "I1_SCP_JTAG0_TMS"), + MTK_FUNCTION(6, "I1_CCU0_JTAG_TMS"), + MTK_FUNCTION(7, "I0_IPU_JTAG_TMS") + ), + + MTK_PIN( + 164, "GPIO164", + MTK_EINT_FUNCTION(0, 164), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO164"), + MTK_FUNCTION(1, "B1_MSDC1_CLK"), + MTK_FUNCTION(2, "I0_SPDIF_IN0"), + MTK_FUNCTION(3, "I1_MD32_0_JTAG_TCK"), + MTK_FUNCTION(4, "I0_ADSP_JTAG0_TCK"), + MTK_FUNCTION(5, "I1_SCP_JTAG0_TCK"), + MTK_FUNCTION(6, "I1_CCU0_JTAG_TCK"), + MTK_FUNCTION(7, "I0_IPU_JTAG_TCK") + ), + + MTK_PIN( + 165, "GPIO165", + MTK_EINT_FUNCTION(0, 165), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO165"), + MTK_FUNCTION(1, "B1_MSDC1_DAT0"), + MTK_FUNCTION(2, "I0_SPDIF_IN1"), + MTK_FUNCTION(3, "I1_MD32_0_JTAG_TDI"), + MTK_FUNCTION(4, "I1_ADSP_JTAG0_TDI"), + MTK_FUNCTION(5, "I1_SCP_JTAG0_TDI"), + MTK_FUNCTION(6, "I1_CCU0_JTAG_TDI"), + MTK_FUNCTION(7, "I0_IPU_JTAG_TDI") + ), + + MTK_PIN( + 166, "GPIO166", + MTK_EINT_FUNCTION(0, 166), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO166"), + MTK_FUNCTION(1, "B1_MSDC1_DAT1"), + MTK_FUNCTION(2, "I0_SPDIF_IN2"), + MTK_FUNCTION(3, "O_MD32_0_JTAG_TDO"), + MTK_FUNCTION(4, "O_ADSP_JTAG0_TDO"), + MTK_FUNCTION(5, "O_SCP_JTAG0_TDO"), + MTK_FUNCTION(6, "O_CCU0_JTAG_TDO"), + MTK_FUNCTION(7, "O_IPU_JTAG_TDO") + ), + + MTK_PIN( + 167, "GPIO167", + MTK_EINT_FUNCTION(0, 167), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO167"), + MTK_FUNCTION(1, "B1_MSDC1_DAT2"), + MTK_FUNCTION(2, "O_PWM_0"), + MTK_FUNCTION(3, "I1_MD32_0_JTAG_TRST"), + MTK_FUNCTION(4, "I1_ADSP_JTAG0_TRSTN"), + MTK_FUNCTION(5, "I0_SCP_JTAG0_TRSTN"), + MTK_FUNCTION(6, "I1_CCU0_JTAG_TRST"), + MTK_FUNCTION(7, "I0_IPU_JTAG_TRST") + ), + + MTK_PIN( + 168, "GPIO168", + MTK_EINT_FUNCTION(0, 168), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO168"), + MTK_FUNCTION(1, "B1_MSDC1_DAT3"), + MTK_FUNCTION(2, "O_PWM_1"), + MTK_FUNCTION(3, "O_CLKM0") + ), + + MTK_PIN( + 169, "GPIO169", + MTK_EINT_FUNCTION(0, 169), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO169"), + MTK_FUNCTION(1, "B1_MSDC2_CMD"), + MTK_FUNCTION(2, "O_LVTS_FOUT"), + MTK_FUNCTION(3, "I1_MD32_1_JTAG_TMS"), + MTK_FUNCTION(4, "I0_UDI_TMS"), + MTK_FUNCTION(5, "I0_VPU_UDI_TMS"), + MTK_FUNCTION(6, "B0_TDMIN_MCK"), + MTK_FUNCTION(7, "I1_SSPM_JTAG_TMS") + ), + + MTK_PIN( + 170, "GPIO170", + MTK_EINT_FUNCTION(0, 170), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO170"), + MTK_FUNCTION(1, "B1_MSDC2_CLK"), + MTK_FUNCTION(2, "O_LVTS_SDO"), + MTK_FUNCTION(3, "I1_MD32_1_JTAG_TCK"), + MTK_FUNCTION(4, "I0_UDI_TCK"), + MTK_FUNCTION(5, "I0_VPU_UDI_TCK"), + MTK_FUNCTION(6, "B0_TDMIN_BCK"), + MTK_FUNCTION(7, "I1_SSPM_JTAG_TCK") + ), + + MTK_PIN( + 171, "GPIO171", + MTK_EINT_FUNCTION(0, 171), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO171"), + MTK_FUNCTION(1, "B1_MSDC2_DAT0"), + MTK_FUNCTION(2, "I0_LVTS_26M"), + MTK_FUNCTION(3, "I1_MD32_1_JTAG_TDI"), + MTK_FUNCTION(4, "I0_UDI_TDI"), + MTK_FUNCTION(5, "I0_VPU_UDI_TDI"), + MTK_FUNCTION(6, "B0_TDMIN_LRCK"), + MTK_FUNCTION(7, "I1_SSPM_JTAG_TDI") + ), + + MTK_PIN( + 172, "GPIO172", + MTK_EINT_FUNCTION(0, 172), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO172"), + MTK_FUNCTION(1, "B1_MSDC2_DAT1"), + MTK_FUNCTION(2, "I0_LVTS_SCF"), + MTK_FUNCTION(3, "O_MD32_1_JTAG_TDO"), + MTK_FUNCTION(4, "O_UDI_TDO"), + MTK_FUNCTION(5, "O_VPU_UDI_TDO"), + MTK_FUNCTION(6, "I0_TDMIN_DI"), + MTK_FUNCTION(7, "O_SSPM_JTAG_TDO") + ), + + MTK_PIN( + 173, "GPIO173", + MTK_EINT_FUNCTION(0, 173), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO173"), + MTK_FUNCTION(1, "B1_MSDC2_DAT2"), + MTK_FUNCTION(2, "I0_LVTS_SCK"), + MTK_FUNCTION(3, "I1_MD32_1_JTAG_TRST"), + MTK_FUNCTION(4, "I0_UDI_NTRST"), + MTK_FUNCTION(5, "I0_VPU_UDI_NTRST"), + MTK_FUNCTION(7, "I0_SSPM_JTAG_TRSTN") + ), + + MTK_PIN( + 174, "GPIO174", + MTK_EINT_FUNCTION(0, 174), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO174"), + MTK_FUNCTION(1, "B1_MSDC2_DAT3"), + MTK_FUNCTION(2, "I0_LVTS_SDI") + ), + + MTK_PIN( + 175, "GPIO175", + MTK_EINT_FUNCTION(0, 175), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO175"), + MTK_FUNCTION(1, "B0_SPMI_M_SCL") + ), + + MTK_PIN( + 176, "GPIO176", + MTK_EINT_FUNCTION(0, 176), + DRV_GRP4, + MTK_FUNCTION(0, "B_GPIO176"), + MTK_FUNCTION(1, "B0_SPMI_M_SDA") + ), + + MTK_PIN( + 177, "GPIO177", + MTK_EINT_FUNCTION(0, 212), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 178, "GPIO178", + MTK_EINT_FUNCTION(0, 213), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 179, "GPIO179", + MTK_EINT_FUNCTION(0, 214), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 180, "GPIO180", + MTK_EINT_FUNCTION(0, 215), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 181, "GPIO181", + MTK_EINT_FUNCTION(0, 216), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 182, "GPIO182", + MTK_EINT_FUNCTION(0, 217), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 183, "GPIO183", + MTK_EINT_FUNCTION(0, 218), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 184, "GPIO184", + MTK_EINT_FUNCTION(0, 219), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 185, "GPIO185", + MTK_EINT_FUNCTION(0, 220), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 186, "GPIO186", + MTK_EINT_FUNCTION(0, 221), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 187, "GPIO187", + MTK_EINT_FUNCTION(0, 222), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 188, "GPIO188", + MTK_EINT_FUNCTION(0, 223), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ), + + MTK_PIN( + 189, "GPIO189", + MTK_EINT_FUNCTION(0, 224), + DRV_FIXED, + MTK_FUNCTION(0, NULL) + ) +}; + +#endif /* __PINCTRL__MTK_MT8188_H */ From 0684bc79cd52edca88e430b177f06d980aed5779 Mon Sep 17 00:00:00 2001 From: Allen-KH Cheng Date: Fri, 19 Aug 2022 20:06:49 +0800 Subject: [PATCH 062/401] dt-bindings: pinctrl: mt8186: Fix 'reg-names' for pinctrl nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mt8186 contains 8 GPIO physical address bases that correspond to the 'reg-names' of the pinctrl driver. The 'reg-names' entries in bindings are ordered incorrectly, though. The system crashes due of an erroneous address when the regulator initializes. We fix the 'reg-names' for the pinctrl nodes and the pinctrl-mt8186 example in bindings. Fixes: 338e953f1bd1 ("dt-bindings: pinctrl: mt8186: add pinctrl file and binding document") Co-developed-by: Guodong Liu Signed-off-by: Guodong Liu Signed-off-by: Allen-KH Cheng Acked-by: Krzysztof Kozlowski Reviewed-by: Nícolas F. R. A. Prado Link: https://lore.kernel.org/r/20220819120649.21523-1-allen-kh.cheng@mediatek.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/pinctrl-mt8186.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml index 1eeb885ce0c6..26573a793b57 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml @@ -41,12 +41,12 @@ properties: Gpio base register names. items: - const: iocfg0 - - const: iocfg_bm - - const: iocfg_bl - - const: iocfg_br + - const: iocfg_lt - const: iocfg_lm + - const: iocfg_lb + - const: iocfg_bl - const: iocfg_rb - - const: iocfg_tl + - const: iocfg_rt - const: eint interrupt-controller: true @@ -235,9 +235,9 @@ examples: <0x10002A00 0x0200>, <0x10002c00 0x0200>, <0x1000b000 0x1000>; - reg-names = "iocfg0", "iocfg_bm", "iocfg_bl", - "iocfg_br", "iocfg_lm", "iocfg_rb", - "iocfg_tl", "eint"; + reg-names = "iocfg0", "iocfg_lt", "iocfg_lm", + "iocfg_lb", "iocfg_bl", "iocfg_rb", + "iocfg_rt", "eint"; gpio-controller; #gpio-cells = <2>; gpio-ranges = <&pio 0 0 185>; From c412a97cf6c5253fcf4ae5545be5775b2417d61b Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Mon, 22 Aug 2022 11:30:12 -0500 Subject: [PATCH 063/401] gfs2: Use TRY lock in gfs2_inode_lookup for UNLINKED inodes Before this patch, delete_work_func() would check for the GLF_DEMOTE flag on the iopen glock and if set, it would perform special processing. However, there was a race whereby the GLF_DEMOTE flag could be set by another process after the check. Then when it called gfs2_lookup_by_inum() which calls gfs2_inode_lookup(), it tried to lock the iopen glock in SH mode, but the GLF_DEMOTE flag prevented the request from being granted. But the iopen glock could never be demoted because that happens when the inode is evicted, and the evict was never completed because of the failed lookup. To fix that, change function gfs2_inode_lookup() so that when GFS2_BLKST_UNLINKED inodes are searched, it uses the LM_FLAG_TRY flag for the iopen glock. If the locking request fails, fail gfs2_inode_lookup() with -EAGAIN so that delete_work_func() can retry the operation later. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/glock.c | 8 +++++--- fs/gfs2/inode.c | 10 ++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 41b6c89e4bf7..57dcfd05b362 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1018,16 +1018,18 @@ static void delete_work_func(struct work_struct *work) if (gfs2_queue_delete_work(gl, 5 * HZ)) return; } - goto out; } inode = gfs2_lookup_by_inum(sdp, no_addr, gl->gl_no_formal_ino, GFS2_BLKST_UNLINKED); - if (!IS_ERR_OR_NULL(inode)) { + if (IS_ERR(inode)) { + if (PTR_ERR(inode) == -EAGAIN && + (gfs2_queue_delete_work(gl, 5 * HZ))) + return; + } else { d_prune_aliases(inode); iput(inode); } -out: gfs2_glock_put(gl); } diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index c8ec876f33ea..56ded979988c 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -130,6 +130,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, if (inode->i_state & I_NEW) { struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_glock *io_gl; + int extra_flags = 0; error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); @@ -141,9 +142,12 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, if (unlikely(error)) goto fail; - if (blktype != GFS2_BLKST_UNLINKED) + if (blktype == GFS2_BLKST_UNLINKED) + extra_flags |= LM_FLAG_TRY; + else gfs2_cancel_delete_work(io_gl); - error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, + error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, + GL_EXACT | extra_flags, &ip->i_iopen_gh); gfs2_glock_put(io_gl); if (unlikely(error)) @@ -210,6 +214,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, return inode; fail: + if (error == GLR_TRYFAILED) + error = -EAGAIN; if (gfs2_holder_initialized(&ip->i_iopen_gh)) gfs2_glock_dq_uninit(&ip->i_iopen_gh); if (gfs2_holder_initialized(&i_gh)) From 04133b607a78f2fd3daadbe5519513942b0f3a05 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Thu, 18 Aug 2022 13:32:36 -0500 Subject: [PATCH 064/401] gfs2: Prevent double iput for journal on error When a gfs2 file system is withdrawn it does iput on its journal to allow recovery from another cluster node. If it's unable to get a replacement inode for whatever reason, the journal descriptor would still be pointing at the evicted inode. So when unmount clears out the list of journals, it would do a second iput referencing the pointer. To avoid this, set the inode pointer to NULL. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 8241029a2a5d..95c79a3ec161 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c @@ -204,6 +204,7 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp) * exception code in glock_dq. */ iput(inode); + sdp->sd_jdesc->jd_inode = NULL; /* * Wait until the journal inode's glock is freed. This allows try locks * on other nodes to be successful, otherwise we remain the owner of From 053640a73838400dca23087d66a9c0db579adafb Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Thu, 18 Aug 2022 13:32:37 -0500 Subject: [PATCH 065/401] gfs2: Dequeue waiters when withdrawn When a withdraw occurs, ordinary (not system) glocks may not be granted anymore. Later, when the file system is unmounted, gfs2_gl_hash_clear() tries to clear out all the glocks, but these un-grantable pending waiters prevent some glocks from being freed. So the unmount hangs, at least for its ten-minute timeout period. This patch takes measures to remove any pending waiters from the glocks that will never be granted. This allows the unmount to proceed in a reasonable period of time. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/glock.c | 14 ++++++++++++++ fs/gfs2/glock.h | 1 + fs/gfs2/util.c | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 57dcfd05b362..858616afcae6 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -2196,6 +2196,20 @@ static void dump_glock_func(struct gfs2_glock *gl) dump_glock(NULL, gl, true); } +static void withdraw_dq(struct gfs2_glock *gl) +{ + spin_lock(&gl->gl_lockref.lock); + if (!__lockref_is_dead(&gl->gl_lockref) && + glock_blocked_by_withdraw(gl)) + do_error(gl, LM_OUT_ERROR); /* remove pending waiters */ + spin_unlock(&gl->gl_lockref.lock); +} + +void gfs2_gl_dq_holders(struct gfs2_sbd *sdp) +{ + glock_hash_walk(withdraw_dq, sdp); +} + /** * gfs2_gl_hash_clear - Empty out the glock hash table * @sdp: the filesystem diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 5aed8b500cf5..0199a3dcb114 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -274,6 +274,7 @@ extern void gfs2_cancel_delete_work(struct gfs2_glock *gl); extern bool gfs2_delete_work_queued(const struct gfs2_glock *gl); extern void gfs2_flush_delete_work(struct gfs2_sbd *sdp); extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp); +extern void gfs2_gl_dq_holders(struct gfs2_sbd *sdp); extern void gfs2_glock_thaw(struct gfs2_sbd *sdp); extern void gfs2_glock_add_to_lru(struct gfs2_glock *gl); extern void gfs2_glock_free(struct gfs2_glock *gl); diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 95c79a3ec161..88185a341504 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c @@ -164,6 +164,11 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp) } if (!ret) gfs2_make_fs_ro(sdp); + /* + * Dequeue any pending non-system glock holders that can no + * longer be granted because the file system is withdrawn. + */ + gfs2_gl_dq_holders(sdp); gfs2_freeze_unlock(&freeze_gh); } From 86934198eefa10a71f35162b06c44c36d85b98ba Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Thu, 18 Aug 2022 13:32:38 -0500 Subject: [PATCH 066/401] gfs2: Clear flags when withdraw prevents xmote There are a couple places in function do_xmote where normal processing is circumvented due to withdraws in progress. However, since we bypass most of do_xmote() we bypass telling dlm to lock the dlm lock, which means dlm will never respond with a completion callback. Since the completion callback ordinarily clears GLF_LOCK, this patch changes function do_xmote to handle those situations more gracefully so the file system may be unmounted after withdraw. A very similar situation happens with the GLF_DEMOTE_IN_PROGRESS flag, which is cleared by function finish_xmote(). Since the withdraw causes us to skip the majority of do_xmote, it therefore also skips the call to finish_xmote() so the DEMOTE_IN_PROGRESS flag needs to be cleared manually. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/glock.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 858616afcae6..dca2cbf0338c 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -59,6 +59,8 @@ typedef void (*glock_examiner) (struct gfs2_glock * gl); static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target); static void __gfs2_glock_dq(struct gfs2_holder *gh); +static void handle_callback(struct gfs2_glock *gl, unsigned int state, + unsigned long delay, bool remote); static struct dentry *gfs2_root; static struct workqueue_struct *glock_workqueue; @@ -730,7 +732,8 @@ static bool is_system_glock(struct gfs2_glock *gl) * */ -static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target) +static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, + unsigned int target) __releases(&gl->gl_lockref.lock) __acquires(&gl->gl_lockref.lock) { @@ -741,7 +744,8 @@ __acquires(&gl->gl_lockref.lock) if (target != LM_ST_UNLOCKED && glock_blocked_by_withdraw(gl) && gh && !(gh->gh_flags & LM_FLAG_NOEXP)) - return; + goto skip_inval; + lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | LM_FLAG_PRIORITY); GLOCK_BUG_ON(gl, gl->gl_state == target); @@ -826,6 +830,20 @@ skip_inval: (target != LM_ST_UNLOCKED || test_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags))) { if (!is_system_glock(gl)) { + handle_callback(gl, LM_ST_UNLOCKED, 0, false); /* sets demote */ + /* + * Ordinarily, we would call dlm and its callback would call + * finish_xmote, which would call state_change() to the new state. + * Since we withdrew, we won't call dlm, so call state_change + * manually, but to the UNLOCKED state we desire. + */ + state_change(gl, LM_ST_UNLOCKED); + /* + * We skip telling dlm to do the locking, so we won't get a + * reply that would otherwise clear GLF_LOCK. So we clear it here. + */ + clear_bit(GLF_LOCK, &gl->gl_flags); + clear_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); gfs2_glock_queue_work(gl, GL_GLOCK_DFT_HOLD); goto out; } else { From 0e1fa5155a364de7d3de770eb382980933376699 Mon Sep 17 00:00:00 2001 From: Russell Currey Date: Sat, 6 Aug 2022 18:53:01 +1000 Subject: [PATCH 067/401] MAINTAINERS: Add Mahesh J Salgaonkar as EEH maintainer Update EEH entry: - Russell: lacks time to maintain EEH. - Oliver: lacks time & hardware to do actual maintenance, but happy to field questions and review things. - Mahesh: glad to take over EEH maintenance. [bhelgaas: commit log, add Mahesh, make Oliver reviewer] Link: https://lore.kernel.org/r/20220806085301.25142-1-ruscur@russell.cc Signed-off-by: Russell Currey Signed-off-by: Bjorn Helgaas Acked-by: Michael Ellerman --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f60dfac7661c..51def5ac9462 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15696,8 +15696,8 @@ F: drivers/pci/endpoint/ F: tools/pci/ PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC -M: Russell Currey -M: Oliver O'Halloran +M: Mahesh J Salgaonkar +R: Oliver O'Halloran L: linuxppc-dev@lists.ozlabs.org S: Supported F: Documentation/PCI/pci-error-recovery.rst From bbe2a5d87602ce0ac206e9f41fca9bd76d75da11 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 26 Aug 2022 15:26:50 +1000 Subject: [PATCH 068/401] pinctrl: fixup for "i2c: Make remove callback return void" Fix up the build. Signed-off-by: Stephen Rothwell Link: https://lore.kernel.org/r/20220826152650.2c55e482@canb.auug.org.au Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index a29df0920f4f..05791212822e 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1352,14 +1352,12 @@ err_exit: return ret; } -static int cy8c95x0_remove(struct i2c_client *client) +static void cy8c95x0_remove(struct i2c_client *client) { struct cy8c95x0_pinctrl *chip = i2c_get_clientdata(client); if (!IS_ERR_OR_NULL(chip->regulator)) regulator_disable(chip->regulator); - - return 0; } static struct i2c_driver cy8c95x0_driver = { From 76e55d938c5bfd2b28ee868fe071181cce5353ad Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 23 Aug 2022 18:07:52 -0500 Subject: [PATCH 069/401] pinctrl: amd: Pick some different unicode symbols Feedback from Kent had showed some better selections for symbols to use for pinctrl-amd debugfs output. Adopt some of those instead. Fixes: e8129a076a50 ("pinctrl: amd: Use unicode for debugfs output") Suggested-by: Kent Gibson Signed-off-by: Mario Limonciello Link: https://lore.kernel.org/r/20220823230753.14799-1-mario.limonciello@amd.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-amd.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 4691a33bc374..fda41907c4f1 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -246,7 +246,7 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) } seq_printf(s, "GPIO bank%d\n", bank); for (; i < pin_num; i++) { - seq_printf(s, "📌%d\t", i); + seq_printf(s, "#%d\t", i); raw_spin_lock_irqsave(&gpio_dev->lock, flags); pin_reg = readl(gpio_dev->base + i * 4); raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); @@ -278,32 +278,32 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) } if (pin_reg & BIT(INTERRUPT_MASK_OFF)) - interrupt_mask = "-"; + interrupt_mask = "😛"; else - interrupt_mask = "+"; - seq_printf(s, "int %s (🎭 %s)| active-%s| %s-🔫| ", + interrupt_mask = "😷"; + seq_printf(s, "int %s (%s)| active-%s| %s-⚡| ", interrupt_enable, interrupt_mask, active_level, level_trig); if (pin_reg & BIT(WAKE_CNTRL_OFF_S0I3)) - wake_cntrl0 = "+"; + wake_cntrl0 = "⏰"; else - wake_cntrl0 = "∅"; - seq_printf(s, "S0i3 🌅 %s| ", wake_cntrl0); + wake_cntrl0 = " ∅"; + seq_printf(s, "S0i3 %s| ", wake_cntrl0); if (pin_reg & BIT(WAKE_CNTRL_OFF_S3)) - wake_cntrl1 = "+"; + wake_cntrl1 = "⏰"; else - wake_cntrl1 = "∅"; - seq_printf(s, "S3 🌅 %s| ", wake_cntrl1); + wake_cntrl1 = " ∅"; + seq_printf(s, "S3 %s| ", wake_cntrl1); if (pin_reg & BIT(WAKE_CNTRL_OFF_S4)) - wake_cntrl2 = "+"; + wake_cntrl2 = "⏰"; else - wake_cntrl2 = "∅"; - seq_printf(s, "S4/S5 🌅 %s| ", wake_cntrl2); + wake_cntrl2 = " ∅"; + seq_printf(s, "S4/S5 %s| ", wake_cntrl2); if (pin_reg & BIT(PULL_UP_ENABLE_OFF)) { pull_up_enable = "+"; @@ -367,7 +367,7 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) debounce_enable = " ∅"; } snprintf(debounce_value, sizeof(debounce_value), "%u", time * unit); - seq_printf(s, "debounce %s (⏰ %sus)| ", debounce_enable, debounce_value); + seq_printf(s, "debounce %s (🕑 %sus)| ", debounce_enable, debounce_value); seq_printf(s, " 0x%x\n", pin_reg); } } From 204c0300c4e99707e9fb6e57840aa1127060e63f Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Fri, 26 Aug 2022 15:12:17 +0200 Subject: [PATCH 070/401] gfs2: Switch from strlcpy to strscpy Switch from strlcpy to strscpy and make sure that @count is the size of the smaller of the source and destination buffers. This prevents reading beyond the end of the source buffer when the source string isn't null terminated. Found by a modified version of syzkaller. Suggested-by: Wolfram Sang Signed-off-by: Andreas Gruenbacher --- fs/gfs2/ops_fstype.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 549879929c84..236b59ef93b6 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -381,8 +381,10 @@ static int init_names(struct gfs2_sbd *sdp, int silent) if (!table[0]) table = sdp->sd_vfs->s_id; - strlcpy(sdp->sd_proto_name, proto, GFS2_FSNAME_LEN); - strlcpy(sdp->sd_table_name, table, GFS2_FSNAME_LEN); + BUILD_BUG_ON(GFS2_LOCKNAME_LEN > GFS2_FSNAME_LEN); + + strscpy(sdp->sd_proto_name, proto, GFS2_LOCKNAME_LEN); + strscpy(sdp->sd_table_name, table, GFS2_LOCKNAME_LEN); table = sdp->sd_table_name; while ((table = strchr(table, '/'))) @@ -1439,13 +1441,13 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param) switch (o) { case Opt_lockproto: - strlcpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN); + strscpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN); break; case Opt_locktable: - strlcpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN); + strscpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN); break; case Opt_hostdata: - strlcpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN); + strscpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN); break; case Opt_spectator: args->ar_spectator = 1; From 9194e0f88a74d98f98b33183e6dda87c3753dd71 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 23 Aug 2022 09:56:37 -0500 Subject: [PATCH 071/401] dt-bindings: pinctrl: Add missing (unevaluated|additional)Properties on child nodes In order to ensure only documented properties are present, node schemas must have unevaluatedProperties or additionalProperties set to false (typically). Signed-off-by: Rob Herring Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220823145649.3118479-6-robh@kernel.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/brcm,bcm4908-pinctrl.yaml | 1 + .../devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml | 1 + .../devicetree/bindings/pinctrl/intel,pinctrl-thunderbay.yaml | 1 + .../devicetree/bindings/pinctrl/marvell,ac5-pinctrl.yaml | 1 + .../devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml | 2 ++ .../devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml | 1 + .../devicetree/bindings/pinctrl/renesas,rza1-ports.yaml | 1 + Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml | 3 +++ .../devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml | 3 +++ .../devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml | 1 + 10 files changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm4908-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/brcm,bcm4908-pinctrl.yaml index 175a992f15e1..8a9fb9b433ca 100644 --- a/Documentation/devicetree/bindings/pinctrl/brcm,bcm4908-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm4908-pinctrl.yaml @@ -23,6 +23,7 @@ patternProperties: '-pins$': type: object $ref: pinmux-node.yaml# + additionalProperties: false properties: function: diff --git a/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml b/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml index 5e99d79499b4..846651ff77c9 100644 --- a/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml +++ b/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml @@ -44,6 +44,7 @@ properties: patternProperties: '^gpio@[0-9a-f]*$': type: object + additionalProperties: false description: Child nodes can be specified to contain pin configuration information, diff --git a/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-thunderbay.yaml b/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-thunderbay.yaml index 0ec476248f21..6f30b5337ca2 100644 --- a/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-thunderbay.yaml +++ b/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-thunderbay.yaml @@ -42,6 +42,7 @@ properties: patternProperties: '^gpio@[0-9a-f]*$': type: object + additionalProperties: false description: Child nodes can be specified to contain pin configuration information, diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,ac5-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/marvell,ac5-pinctrl.yaml index a651b2744caf..491f67e7cc4f 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,ac5-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/marvell,ac5-pinctrl.yaml @@ -24,6 +24,7 @@ patternProperties: '-pins$': type: object $ref: pinmux-node.yaml# + additionalProperties: false properties: marvell,function: diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml index e7601c0f5a69..840f649e36ce 100644 --- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml @@ -76,6 +76,8 @@ required: patternProperties: '-[0-9]*$': type: object + additionalProperties: false + patternProperties: '-pins*$': type: object diff --git a/Documentation/devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml index 7a11beb8f222..7b7f840ffc4c 100644 --- a/Documentation/devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/nuvoton,wpcm450-pinctrl.yaml @@ -30,6 +30,7 @@ patternProperties: "^gpio@[0-7]$": type: object + additionalProperties: false description: Eight GPIO banks (gpio@0 to gpio@7), that each contain between 14 and 18 diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rza1-ports.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rza1-ports.yaml index 8ed4b98a1628..9083040c996a 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,rza1-ports.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rza1-ports.yaml @@ -41,6 +41,7 @@ required: patternProperties: "^gpio-[0-9]*$": type: object + additionalProperties: false description: Each port of the r7s72100 pin controller hardware is itself a GPIO diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml index 3a65c66ca71d..d006a940c7c6 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml @@ -97,6 +97,9 @@ patternProperties: additionalProperties: false "^(initial|sleep)-state$": + type: object + additionalProperties: false + patternProperties: "^(pin-[a-z0-9-]+|[a-z0-9-]+-pin)$": $ref: samsung,pinctrl-pins-cfg.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml index d35dcc4f0242..53c952d93ea2 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -115,9 +115,12 @@ patternProperties: '-[0-9]*$': type: object + additionalProperties: false + patternProperties: '^pins': type: object + additionalProperties: false description: | A pinctrl node should contain at least one subnode representing the pinctrl group available on the machine. Each subnode will list the diff --git a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml index 306524885a2b..98b4663f9766 100644 --- a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml @@ -36,6 +36,7 @@ patternProperties: pins it needs, and how they should be configured, with regard to muxer configuration, pullups, drive strength. $ref: "pinmux-node.yaml" + additionalProperties: false properties: function: From 1ebfe7e36182a658819e4ded44d38d4033c8bbfb Mon Sep 17 00:00:00 2001 From: Jilin Yuan Date: Thu, 25 Aug 2022 20:41:34 +0800 Subject: [PATCH 072/401] pinctrl: nuvoton: Use 'unsigned int' instead of just 'unsigned'. 'unsigned int' should be clearer than 'unsigned'. Signed-off-by: Jilin Yuan Link: https://lore.kernel.org/r/20220825124134.30242-1-yuanjilin@cdjrlc.com Signed-off-by: Linus Walleij --- drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c index 64d8a568b3db..1c4e89b046de 100644 --- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c +++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c @@ -81,11 +81,11 @@ struct npcm7xx_gpio { int irq; struct irq_chip irq_chip; u32 pinctrl_id; - int (*direction_input)(struct gpio_chip *chip, unsigned offset); - int (*direction_output)(struct gpio_chip *chip, unsigned offset, + int (*direction_input)(struct gpio_chip *chip, unsigned int offset); + int (*direction_output)(struct gpio_chip *chip, unsigned int offset, int value); - int (*request)(struct gpio_chip *chip, unsigned offset); - void (*free)(struct gpio_chip *chip, unsigned offset); + int (*request)(struct gpio_chip *chip, unsigned int offset); + void (*free)(struct gpio_chip *chip, unsigned int offset); }; struct npcm7xx_pinctrl { From 2b96f92ca4257c05e352f61742839b451e293949 Mon Sep 17 00:00:00 2001 From: Josef Johansson Date: Mon, 14 Feb 2022 11:07:47 +0100 Subject: [PATCH 073/401] PCI/MSI: Correct 'can_mask' test in msi_add_msi_desc() 71020a3c0dff4 ("PCI/MSI: Use msi_add_msi_desc()") inadvertently reversed the sense of "msi_attrib.can_mask" in one use: - if (entry->pci.msi_attrib.can_mask) { - addr = pci_msix_desc_addr(entry); - entry->pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); + if (!desc.pci.msi_attrib.can_mask) { + addr = pci_msix_desc_addr(&desc); + desc.pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); Restore the original test. [bhelgaas: commit log] Fixes: 71020a3c0dff4 ("PCI/MSI: Use msi_add_msi_desc()") Link: https://lore.kernel.org/r/d818f9c9-a432-213e-4152-eaff3b7da52e@oderland.se Signed-off-by: Josef Johansson Signed-off-by: Bjorn Helgaas Reviewed-by: Jason Gunthorpe --- drivers/pci/msi/msi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index 9037a7827eca..fdd2ec09651e 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -526,7 +526,7 @@ static int msix_setup_msi_descs(struct pci_dev *dev, void __iomem *base, desc.pci.msi_attrib.can_mask = !pci_msi_ignore_mask && !desc.pci.msi_attrib.is_virtual; - if (!desc.pci.msi_attrib.can_mask) { + if (desc.pci.msi_attrib.can_mask) { addr = pci_msix_desc_addr(&desc); desc.pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); } From 423511ec23e2a6fa7830ed76b0283268e795d09d Mon Sep 17 00:00:00 2001 From: Will McVicker Date: Thu, 25 Aug 2022 23:54:02 +0000 Subject: [PATCH 074/401] PCI: dwc: Drop dependency on ZONE_DMA32 Re-work the msi_msg DMA allocation logic to use dmam_alloc_coherent() which uses the coherent DMA mask to try to return an allocation within the DMA mask limits. With that, we now can drop the msi_page parameter in struct dw_pcie_rp. This allows kernel configurations that disable ZONE_DMA32 to continue supporting a 32-bit DMA mask. Without this patch, the PCIe host device will fail to probe when ZONE_DMA32 is disabled. Link: https://lore.kernel.org/r/20220825235404.4132818-2-willmcvicker@google.com Fixes: 35797e672ff0 ("PCI: dwc: Fix MSI msi_msg DMA mapping") Reported-by: Isaac J. Manjarres Signed-off-by: Will McVicker Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring Acked-by: Jingoo Han --- .../pci/controller/dwc/pcie-designware-host.c | 28 +++++-------------- drivers/pci/controller/dwc/pcie-designware.h | 1 - 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 7746f94a715f..39f3b37d4033 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -267,15 +267,6 @@ static void dw_pcie_free_msi(struct dw_pcie_rp *pp) irq_domain_remove(pp->msi_domain); irq_domain_remove(pp->irq_domain); - - if (pp->msi_data) { - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - struct device *dev = pci->dev; - - dma_unmap_page(dev, pp->msi_data, PAGE_SIZE, DMA_FROM_DEVICE); - if (pp->msi_page) - __free_page(pp->msi_page); - } } static void dw_pcie_msi_init(struct dw_pcie_rp *pp) @@ -336,6 +327,7 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp) struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct device *dev = pci->dev; struct platform_device *pdev = to_platform_device(dev); + u64 *msi_vaddr; int ret; u32 ctrl, num_ctrls; @@ -375,22 +367,16 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp) dw_chained_msi_isr, pp); } - ret = dma_set_mask(dev, DMA_BIT_MASK(32)); + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n"); - pp->msi_page = alloc_page(GFP_DMA32); - pp->msi_data = dma_map_page(dev, pp->msi_page, 0, - PAGE_SIZE, DMA_FROM_DEVICE); - ret = dma_mapping_error(dev, pp->msi_data); - if (ret) { - dev_err(pci->dev, "Failed to map MSI data\n"); - __free_page(pp->msi_page); - pp->msi_page = NULL; - pp->msi_data = 0; + msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data, + GFP_KERNEL); + if (!msi_vaddr) { + dev_err(dev, "Failed to alloc and map MSI data\n"); dw_pcie_free_msi(pp); - - return ret; + return -ENOMEM; } return 0; diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 09b887093a84..a871ae7eb59e 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -243,7 +243,6 @@ struct dw_pcie_rp { struct irq_domain *irq_domain; struct irq_domain *msi_domain; dma_addr_t msi_data; - struct page *msi_page; struct irq_chip *msi_irq_chip; u32 num_vectors; u32 irq_mask[MAX_MSI_CTRLS]; From 80dc113aaa47c0d1dfd01f708d4d0c083022121b Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 11 Aug 2022 15:53:34 -0700 Subject: [PATCH 075/401] f2fs: LFS mode does not support ATGC ATGC is using SSR which violates LFS mode used by zoned device. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2451623c05a7..fe462484f5fa 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1342,6 +1342,11 @@ default_check: return -EINVAL; } + if (test_opt(sbi, ATGC) && f2fs_lfs_mode(sbi)) { + f2fs_err(sbi, "LFS not compatible with ATGC"); + return -EINVAL; + } + if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) { f2fs_err(sbi, "Allow to mount readonly mode only"); return -EROFS; From 605b0a778aa2599aa902ae639b8e9937c74b869b Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 12 Aug 2022 22:49:50 -0700 Subject: [PATCH 076/401] f2fs: fix wrong continue condition in GC We should decrease the frozen counter. Cc: stable@vger.kernel.org Fixes: 325163e9892b ("f2fs: add gc_urgent_high_remaining sysfs node") Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 6da21d405ce1..45f90e3c46d4 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -97,14 +97,10 @@ static int gc_thread_func(void *data) */ if (sbi->gc_mode == GC_URGENT_HIGH) { spin_lock(&sbi->gc_urgent_high_lock); - if (sbi->gc_urgent_high_limited) { - if (!sbi->gc_urgent_high_remaining) { - sbi->gc_urgent_high_limited = false; - spin_unlock(&sbi->gc_urgent_high_lock); - sbi->gc_mode = GC_NORMAL; - continue; - } - sbi->gc_urgent_high_remaining--; + if (sbi->gc_urgent_high_limited && + !sbi->gc_urgent_high_remaining--) { + sbi->gc_urgent_high_limited = false; + sbi->gc_mode = GC_NORMAL; } spin_unlock(&sbi->gc_urgent_high_lock); } From b87846bd61c7c09560617da416208a5454530d57 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 19 Aug 2022 15:33:00 -0700 Subject: [PATCH 077/401] f2fs: use memcpy_{to,from}_page() where possible This is simpler, and as a side effect it replaces several uses of kmap_atomic() with its recommended replacement kmap_local_page(). Signed-off-by: Eric Biggers Reviewed-by: Fabio M. De Francesco Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/inline.c | 15 ++++----------- fs/f2fs/super.c | 11 ++--------- fs/f2fs/verity.c | 10 ++-------- 3 files changed, 8 insertions(+), 28 deletions(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index bf46a7dfbea2..73da93318036 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -64,7 +64,6 @@ bool f2fs_may_inline_dentry(struct inode *inode) void f2fs_do_read_inline_data(struct page *page, struct page *ipage) { struct inode *inode = page->mapping->host; - void *src_addr, *dst_addr; if (PageUptodate(page)) return; @@ -74,11 +73,8 @@ void f2fs_do_read_inline_data(struct page *page, struct page *ipage) zero_user_segment(page, MAX_INLINE_DATA(inode), PAGE_SIZE); /* Copy the whole inline data block */ - src_addr = inline_data_addr(inode, ipage); - dst_addr = kmap_atomic(page); - memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); - flush_dcache_page(page); - kunmap_atomic(dst_addr); + memcpy_to_page(page, 0, inline_data_addr(inode, ipage), + MAX_INLINE_DATA(inode)); if (!PageUptodate(page)) SetPageUptodate(page); } @@ -246,7 +242,6 @@ out: int f2fs_write_inline_data(struct inode *inode, struct page *page) { - void *src_addr, *dst_addr; struct dnode_of_data dn; int err; @@ -263,10 +258,8 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page) f2fs_bug_on(F2FS_I_SB(inode), page->index); f2fs_wait_on_page_writeback(dn.inode_page, NODE, true, true); - src_addr = kmap_atomic(page); - dst_addr = inline_data_addr(inode, dn.inode_page); - memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); - kunmap_atomic(src_addr); + memcpy_from_page(inline_data_addr(inode, dn.inode_page), + page, 0, MAX_INLINE_DATA(inode)); set_page_dirty(dn.inode_page); f2fs_clear_page_cache_dirty_tag(page); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index fe462484f5fa..e910f0e39d76 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2470,7 +2470,6 @@ static ssize_t f2fs_quota_read(struct super_block *sb, int type, char *data, size_t toread; loff_t i_size = i_size_read(inode); struct page *page; - char *kaddr; if (off > i_size) return 0; @@ -2503,9 +2502,7 @@ repeat: return -EIO; } - kaddr = kmap_atomic(page); - memcpy(data, kaddr + offset, tocopy); - kunmap_atomic(kaddr); + memcpy_from_page(data, page, offset, tocopy); f2fs_put_page(page, 1); offset = 0; @@ -2527,7 +2524,6 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, size_t towrite = len; struct page *page; void *fsdata = NULL; - char *kaddr; int err = 0; int tocopy; @@ -2546,10 +2542,7 @@ retry: break; } - kaddr = kmap_atomic(page); - memcpy(kaddr + offset, data, tocopy); - kunmap_atomic(kaddr); - flush_dcache_page(page); + memcpy_to_page(page, offset, data, tocopy); a_ops->write_end(NULL, mapping, off, tocopy, tocopy, page, fsdata); diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c index 7b8f2b41c29b..97ec60f39d69 100644 --- a/fs/f2fs/verity.c +++ b/fs/f2fs/verity.c @@ -47,16 +47,13 @@ static int pagecache_read(struct inode *inode, void *buf, size_t count, size_t n = min_t(size_t, count, PAGE_SIZE - offset_in_page(pos)); struct page *page; - void *addr; page = read_mapping_page(inode->i_mapping, pos >> PAGE_SHIFT, NULL); if (IS_ERR(page)) return PTR_ERR(page); - addr = kmap_atomic(page); - memcpy(buf, addr + offset_in_page(pos), n); - kunmap_atomic(addr); + memcpy_from_page(buf, page, offset_in_page(pos), n); put_page(page); @@ -85,16 +82,13 @@ static int pagecache_write(struct inode *inode, const void *buf, size_t count, PAGE_SIZE - offset_in_page(pos)); struct page *page; void *fsdata; - void *addr; int res; res = aops->write_begin(NULL, mapping, pos, n, &page, &fsdata); if (res) return res; - addr = kmap_atomic(page); - memcpy(addr + offset_in_page(pos), buf, n); - kunmap_atomic(addr); + memcpy_to_page(page, offset_in_page(pos), buf, n); res = aops->write_end(NULL, mapping, pos, n, n, page, fsdata); if (res < 0) From 34a23525601a16f625b48c3bb0a67fbc795810b3 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Sat, 20 Aug 2022 11:04:41 +0800 Subject: [PATCH 078/401] f2fs: iostat: support accounting compressed IO Previously, we supported to account FS_CDATA_READ_IO type IO only, in this patch, it adds to account more type IO for compressed file: - APP_BUFFERED_CDATA_IO - APP_MAPPED_CDATA_IO - FS_CDATA_IO - APP_BUFFERED_CDATA_READ_IO - APP_MAPPED_CDATA_READ_IO Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 5 ++- fs/f2fs/data.c | 8 ++-- fs/f2fs/f2fs.h | 5 +++ fs/f2fs/file.c | 16 ++++---- fs/f2fs/gc.c | 12 +++--- fs/f2fs/iostat.c | 74 ++++++++++++++++++++++++++----------- fs/f2fs/iostat.h | 4 +- fs/f2fs/node.c | 2 +- fs/f2fs/segment.c | 11 +++--- include/trace/events/f2fs.h | 24 +++++++++--- 10 files changed, 109 insertions(+), 52 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 8259e0fa97e1..7de48e791920 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -89,7 +89,7 @@ repeat: return ERR_PTR(err); } - f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, NULL, FS_META_READ_IO, F2FS_BLKSIZE); lock_page(page); if (unlikely(page->mapping != mapping)) { @@ -276,7 +276,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, f2fs_put_page(page, err ? 1 : 0); if (!err) - f2fs_update_iostat(sbi, FS_META_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, NULL, FS_META_READ_IO, + F2FS_BLKSIZE); } out: blk_finish_plug(&plug); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index aa3ccddfa037..0869fbbb5516 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1083,7 +1083,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page, } ClearPageError(page); inc_page_count(sbi, F2FS_RD_DATA); - f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, NULL, FS_DATA_READ_IO, F2FS_BLKSIZE); __submit_bio(sbi, bio, DATA); return 0; } @@ -2122,7 +2122,8 @@ submit_and_realloc: goto submit_and_realloc; inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA); - f2fs_update_iostat(F2FS_I_SB(inode), FS_DATA_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(F2FS_I_SB(inode), NULL, FS_DATA_READ_IO, + F2FS_BLKSIZE); ClearPageError(page); *last_block_in_bio = block_nr; goto out; @@ -2270,8 +2271,7 @@ submit_and_realloc: refcount_inc(&dic->refcnt); inc_page_count(sbi, F2FS_RD_DATA); - f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE); - f2fs_update_iostat(sbi, FS_CDATA_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, inode, FS_DATA_READ_IO, F2FS_BLKSIZE); ClearPageError(page); *last_block_in_bio = blkaddr; } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 3c7cdb70fe2e..809419a258ed 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1158,7 +1158,10 @@ enum iostat_type { APP_BUFFERED_IO, /* app buffered write IOs */ APP_WRITE_IO, /* app write IOs */ APP_MAPPED_IO, /* app mapped IOs */ + APP_BUFFERED_CDATA_IO, /* app buffered write IOs on compressed file */ + APP_MAPPED_CDATA_IO, /* app mapped write IOs on compressed file */ FS_DATA_IO, /* data IOs from kworker/fsync/reclaimer */ + FS_CDATA_IO, /* data IOs from kworker/fsync/reclaimer on compressed file */ FS_NODE_IO, /* node IOs from kworker/fsync/reclaimer */ FS_META_IO, /* meta IOs from kworker/reclaimer */ FS_GC_DATA_IO, /* data IOs from forground gc */ @@ -1172,6 +1175,8 @@ enum iostat_type { APP_BUFFERED_READ_IO, /* app buffered read IOs */ APP_READ_IO, /* app read IOs */ APP_MAPPED_READ_IO, /* app mapped read IOs */ + APP_BUFFERED_CDATA_READ_IO, /* app buffered read IOs on compressed file */ + APP_MAPPED_CDATA_READ_IO, /* app mapped read IOs on compressed file */ FS_DATA_READ_IO, /* data read IOs */ FS_GDATA_READ_IO, /* data read IOs from background gc */ FS_CDATA_READ_IO, /* compressed data read IOs */ diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index ce4905a073b3..771f1f7f3690 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -43,8 +43,8 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) ret = filemap_fault(vmf); if (!ret) - f2fs_update_iostat(F2FS_I_SB(inode), APP_MAPPED_READ_IO, - F2FS_BLKSIZE); + f2fs_update_iostat(F2FS_I_SB(inode), inode, + APP_MAPPED_READ_IO, F2FS_BLKSIZE); trace_f2fs_filemap_fault(inode, vmf->pgoff, (unsigned long)ret); @@ -154,7 +154,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) if (!PageUptodate(page)) SetPageUptodate(page); - f2fs_update_iostat(sbi, APP_MAPPED_IO, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, inode, APP_MAPPED_IO, F2FS_BLKSIZE); f2fs_update_time(sbi, REQ_TIME); trace_f2fs_vm_page_mkwrite(page, DATA); @@ -4212,7 +4212,7 @@ static int f2fs_dio_read_end_io(struct kiocb *iocb, ssize_t size, int error, dec_page_count(sbi, F2FS_DIO_READ); if (error) return error; - f2fs_update_iostat(sbi, APP_DIRECT_READ_IO, size); + f2fs_update_iostat(sbi, NULL, APP_DIRECT_READ_IO, size); return 0; } @@ -4301,7 +4301,8 @@ skip_read_trace: } else { ret = filemap_read(iocb, to, 0); if (ret > 0) - f2fs_update_iostat(F2FS_I_SB(inode), APP_BUFFERED_READ_IO, ret); + f2fs_update_iostat(F2FS_I_SB(inode), inode, + APP_BUFFERED_READ_IO, ret); } if (trace_f2fs_dataread_end_enabled()) trace_f2fs_dataread_end(inode, pos, ret); @@ -4418,7 +4419,8 @@ static ssize_t f2fs_buffered_write_iter(struct kiocb *iocb, if (ret > 0) { iocb->ki_pos += ret; - f2fs_update_iostat(F2FS_I_SB(inode), APP_BUFFERED_IO, ret); + f2fs_update_iostat(F2FS_I_SB(inode), inode, + APP_BUFFERED_IO, ret); } return ret; } @@ -4431,7 +4433,7 @@ static int f2fs_dio_write_end_io(struct kiocb *iocb, ssize_t size, int error, dec_page_count(sbi, F2FS_DIO_WRITE); if (error) return error; - f2fs_update_iostat(sbi, APP_DIRECT_IO, size); + f2fs_update_iostat(sbi, NULL, APP_DIRECT_IO, size); return 0; } diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 45f90e3c46d4..2a3816c20f84 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1202,8 +1202,8 @@ got_it: f2fs_put_page(fio.encrypted_page, 0); f2fs_put_page(page, 1); - f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE); - f2fs_update_iostat(sbi, FS_GDATA_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, inode, FS_DATA_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, NULL, FS_GDATA_READ_IO, F2FS_BLKSIZE); return 0; put_encrypted_page: @@ -1303,8 +1303,10 @@ static int move_data_block(struct inode *inode, block_t bidx, goto up_out; } - f2fs_update_iostat(fio.sbi, FS_DATA_READ_IO, F2FS_BLKSIZE); - f2fs_update_iostat(fio.sbi, FS_GDATA_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(fio.sbi, inode, FS_DATA_READ_IO, + F2FS_BLKSIZE); + f2fs_update_iostat(fio.sbi, NULL, FS_GDATA_READ_IO, + F2FS_BLKSIZE); lock_page(mpage); if (unlikely(mpage->mapping != META_MAPPING(fio.sbi) || @@ -1356,7 +1358,7 @@ static int move_data_block(struct inode *inode, block_t bidx, goto put_page_out; } - f2fs_update_iostat(fio.sbi, FS_GC_DATA_IO, F2FS_BLKSIZE); + f2fs_update_iostat(fio.sbi, NULL, FS_GC_DATA_IO, F2FS_BLKSIZE); f2fs_update_data_blkaddr(&dn, newaddr); set_inode_flag(inode, FI_APPEND_WRITE); diff --git a/fs/f2fs/iostat.c b/fs/f2fs/iostat.c index d84c5f6cc09d..3166a8939ed4 100644 --- a/fs/f2fs/iostat.c +++ b/fs/f2fs/iostat.c @@ -31,55 +31,65 @@ int __maybe_unused iostat_info_seq_show(struct seq_file *seq, void *offset) /* print app write IOs */ seq_puts(seq, "[WRITE]\n"); - seq_printf(seq, "app buffered: %-16llu\n", + seq_printf(seq, "app buffered data: %-16llu\n", sbi->rw_iostat[APP_BUFFERED_IO]); - seq_printf(seq, "app direct: %-16llu\n", + seq_printf(seq, "app direct data: %-16llu\n", sbi->rw_iostat[APP_DIRECT_IO]); - seq_printf(seq, "app mapped: %-16llu\n", + seq_printf(seq, "app mapped data: %-16llu\n", sbi->rw_iostat[APP_MAPPED_IO]); + seq_printf(seq, "app buffered cdata: %-16llu\n", + sbi->rw_iostat[APP_BUFFERED_CDATA_IO]); + seq_printf(seq, "app mapped cdata: %-16llu\n", + sbi->rw_iostat[APP_MAPPED_CDATA_IO]); /* print fs write IOs */ - seq_printf(seq, "fs data: %-16llu\n", + seq_printf(seq, "fs data: %-16llu\n", sbi->rw_iostat[FS_DATA_IO]); - seq_printf(seq, "fs node: %-16llu\n", + seq_printf(seq, "fs cdata: %-16llu\n", + sbi->rw_iostat[FS_CDATA_IO]); + seq_printf(seq, "fs node: %-16llu\n", sbi->rw_iostat[FS_NODE_IO]); - seq_printf(seq, "fs meta: %-16llu\n", + seq_printf(seq, "fs meta: %-16llu\n", sbi->rw_iostat[FS_META_IO]); - seq_printf(seq, "fs gc data: %-16llu\n", + seq_printf(seq, "fs gc data: %-16llu\n", sbi->rw_iostat[FS_GC_DATA_IO]); - seq_printf(seq, "fs gc node: %-16llu\n", + seq_printf(seq, "fs gc node: %-16llu\n", sbi->rw_iostat[FS_GC_NODE_IO]); - seq_printf(seq, "fs cp data: %-16llu\n", + seq_printf(seq, "fs cp data: %-16llu\n", sbi->rw_iostat[FS_CP_DATA_IO]); - seq_printf(seq, "fs cp node: %-16llu\n", + seq_printf(seq, "fs cp node: %-16llu\n", sbi->rw_iostat[FS_CP_NODE_IO]); - seq_printf(seq, "fs cp meta: %-16llu\n", + seq_printf(seq, "fs cp meta: %-16llu\n", sbi->rw_iostat[FS_CP_META_IO]); /* print app read IOs */ seq_puts(seq, "[READ]\n"); - seq_printf(seq, "app buffered: %-16llu\n", + seq_printf(seq, "app buffered data: %-16llu\n", sbi->rw_iostat[APP_BUFFERED_READ_IO]); - seq_printf(seq, "app direct: %-16llu\n", + seq_printf(seq, "app direct data: %-16llu\n", sbi->rw_iostat[APP_DIRECT_READ_IO]); - seq_printf(seq, "app mapped: %-16llu\n", + seq_printf(seq, "app mapped data: %-16llu\n", sbi->rw_iostat[APP_MAPPED_READ_IO]); + seq_printf(seq, "app buffered cdata: %-16llu\n", + sbi->rw_iostat[APP_BUFFERED_CDATA_READ_IO]); + seq_printf(seq, "app mapped cdata: %-16llu\n", + sbi->rw_iostat[APP_MAPPED_CDATA_READ_IO]); /* print fs read IOs */ - seq_printf(seq, "fs data: %-16llu\n", + seq_printf(seq, "fs data: %-16llu\n", sbi->rw_iostat[FS_DATA_READ_IO]); - seq_printf(seq, "fs gc data: %-16llu\n", + seq_printf(seq, "fs gc data: %-16llu\n", sbi->rw_iostat[FS_GDATA_READ_IO]); - seq_printf(seq, "fs compr_data: %-16llu\n", + seq_printf(seq, "fs cdata: %-16llu\n", sbi->rw_iostat[FS_CDATA_READ_IO]); - seq_printf(seq, "fs node: %-16llu\n", + seq_printf(seq, "fs node: %-16llu\n", sbi->rw_iostat[FS_NODE_READ_IO]); - seq_printf(seq, "fs meta: %-16llu\n", + seq_printf(seq, "fs meta: %-16llu\n", sbi->rw_iostat[FS_META_READ_IO]); /* print other IOs */ seq_puts(seq, "[OTHER]\n"); - seq_printf(seq, "fs discard: %-16llu\n", + seq_printf(seq, "fs discard: %-16llu\n", sbi->rw_iostat[FS_DISCARD]); return 0; @@ -159,7 +169,7 @@ void f2fs_reset_iostat(struct f2fs_sb_info *sbi) spin_unlock_irq(&sbi->iostat_lat_lock); } -void f2fs_update_iostat(struct f2fs_sb_info *sbi, +void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode, enum iostat_type type, unsigned long long io_bytes) { unsigned long flags; @@ -176,6 +186,28 @@ void f2fs_update_iostat(struct f2fs_sb_info *sbi, if (type == APP_BUFFERED_READ_IO || type == APP_DIRECT_READ_IO) sbi->rw_iostat[APP_READ_IO] += io_bytes; +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (inode && f2fs_compressed_file(inode)) { + if (type == APP_BUFFERED_IO) + sbi->rw_iostat[APP_BUFFERED_CDATA_IO] += io_bytes; + + if (type == APP_BUFFERED_READ_IO) + sbi->rw_iostat[APP_BUFFERED_CDATA_READ_IO] += io_bytes; + + if (type == APP_MAPPED_READ_IO) + sbi->rw_iostat[APP_MAPPED_CDATA_READ_IO] += io_bytes; + + if (type == APP_MAPPED_IO) + sbi->rw_iostat[APP_MAPPED_CDATA_IO] += io_bytes; + + if (type == FS_DATA_READ_IO) + sbi->rw_iostat[FS_CDATA_READ_IO] += io_bytes; + + if (type == FS_DATA_IO) + sbi->rw_iostat[FS_CDATA_IO] += io_bytes; + } +#endif + spin_unlock_irqrestore(&sbi->iostat_lock, flags); f2fs_record_iostat(sbi); diff --git a/fs/f2fs/iostat.h b/fs/f2fs/iostat.h index 22a2d01f57ef..2c048307b6e0 100644 --- a/fs/f2fs/iostat.h +++ b/fs/f2fs/iostat.h @@ -31,7 +31,7 @@ struct iostat_lat_info { extern int __maybe_unused iostat_info_seq_show(struct seq_file *seq, void *offset); extern void f2fs_reset_iostat(struct f2fs_sb_info *sbi); -extern void f2fs_update_iostat(struct f2fs_sb_info *sbi, +extern void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode, enum iostat_type type, unsigned long long io_bytes); struct bio_iostat_ctx { @@ -65,7 +65,7 @@ extern void f2fs_destroy_iostat_processing(void); extern int f2fs_init_iostat(struct f2fs_sb_info *sbi); extern void f2fs_destroy_iostat(struct f2fs_sb_info *sbi); #else -static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi, +static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode, enum iostat_type type, unsigned long long io_bytes) {} static inline void iostat_update_and_unbind_ctx(struct bio *bio, int rw) {} static inline void iostat_alloc_and_bind_ctx(struct f2fs_sb_info *sbi, diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index e06a0c478b39..2484285be3ad 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1369,7 +1369,7 @@ static int read_node_page(struct page *page, blk_opf_t op_flags) err = f2fs_submit_page_bio(&fio); if (!err) - f2fs_update_iostat(sbi, FS_NODE_READ_IO, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, NULL, FS_NODE_READ_IO, F2FS_BLKSIZE); return err; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 0de21f82d7bc..a5054725d0b6 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1171,7 +1171,7 @@ submit: atomic_inc(&dcc->issued_discard); - f2fs_update_iostat(sbi, FS_DISCARD, 1); + f2fs_update_iostat(sbi, NULL, FS_DISCARD, 1); lstart += len; start += len; @@ -3388,7 +3388,7 @@ void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page, f2fs_submit_page_write(&fio); stat_inc_meta_count(sbi, page->index); - f2fs_update_iostat(sbi, io_type, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, NULL, io_type, F2FS_BLKSIZE); } void f2fs_do_write_node_page(unsigned int nid, struct f2fs_io_info *fio) @@ -3398,7 +3398,7 @@ void f2fs_do_write_node_page(unsigned int nid, struct f2fs_io_info *fio) set_summary(&sum, nid, 0, 0); do_write_page(&sum, fio); - f2fs_update_iostat(fio->sbi, fio->io_type, F2FS_BLKSIZE); + f2fs_update_iostat(fio->sbi, NULL, fio->io_type, F2FS_BLKSIZE); } void f2fs_outplace_write_data(struct dnode_of_data *dn, @@ -3412,7 +3412,7 @@ void f2fs_outplace_write_data(struct dnode_of_data *dn, do_write_page(&sum, fio); f2fs_update_data_blkaddr(dn, fio->new_blkaddr); - f2fs_update_iostat(sbi, fio->io_type, F2FS_BLKSIZE); + f2fs_update_iostat(sbi, dn->inode, fio->io_type, F2FS_BLKSIZE); } int f2fs_inplace_write_data(struct f2fs_io_info *fio) @@ -3453,7 +3453,8 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio) if (!err) { f2fs_update_device_state(fio->sbi, fio->ino, fio->new_blkaddr, 1); - f2fs_update_iostat(fio->sbi, fio->io_type, F2FS_BLKSIZE); + f2fs_update_iostat(fio->sbi, fio->page->mapping->host, + fio->io_type, F2FS_BLKSIZE); } return err; diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index f1e922237736..b262985f0c3a 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -1823,7 +1823,10 @@ TRACE_EVENT(f2fs_iostat, __field(unsigned long long, app_bio) __field(unsigned long long, app_wio) __field(unsigned long long, app_mio) + __field(unsigned long long, app_bcdio) + __field(unsigned long long, app_mcdio) __field(unsigned long long, fs_dio) + __field(unsigned long long, fs_cdio) __field(unsigned long long, fs_nio) __field(unsigned long long, fs_mio) __field(unsigned long long, fs_gc_dio) @@ -1835,6 +1838,8 @@ TRACE_EVENT(f2fs_iostat, __field(unsigned long long, app_brio) __field(unsigned long long, app_rio) __field(unsigned long long, app_mrio) + __field(unsigned long long, app_bcrio) + __field(unsigned long long, app_mcrio) __field(unsigned long long, fs_drio) __field(unsigned long long, fs_gdrio) __field(unsigned long long, fs_cdrio) @@ -1849,7 +1854,10 @@ TRACE_EVENT(f2fs_iostat, __entry->app_bio = iostat[APP_BUFFERED_IO]; __entry->app_wio = iostat[APP_WRITE_IO]; __entry->app_mio = iostat[APP_MAPPED_IO]; + __entry->app_bcdio = iostat[APP_BUFFERED_CDATA_IO]; + __entry->app_mcdio = iostat[APP_MAPPED_CDATA_IO]; __entry->fs_dio = iostat[FS_DATA_IO]; + __entry->fs_cdio = iostat[FS_CDATA_IO]; __entry->fs_nio = iostat[FS_NODE_IO]; __entry->fs_mio = iostat[FS_META_IO]; __entry->fs_gc_dio = iostat[FS_GC_DATA_IO]; @@ -1861,6 +1869,8 @@ TRACE_EVENT(f2fs_iostat, __entry->app_brio = iostat[APP_BUFFERED_READ_IO]; __entry->app_rio = iostat[APP_READ_IO]; __entry->app_mrio = iostat[APP_MAPPED_READ_IO]; + __entry->app_bcrio = iostat[APP_BUFFERED_CDATA_READ_IO]; + __entry->app_mcrio = iostat[APP_MAPPED_CDATA_READ_IO]; __entry->fs_drio = iostat[FS_DATA_READ_IO]; __entry->fs_gdrio = iostat[FS_GDATA_READ_IO]; __entry->fs_cdrio = iostat[FS_CDATA_READ_IO]; @@ -1870,20 +1880,24 @@ TRACE_EVENT(f2fs_iostat, ), TP_printk("dev = (%d,%d), " - "app [write=%llu (direct=%llu, buffered=%llu), mapped=%llu], " - "fs [data=%llu, node=%llu, meta=%llu, discard=%llu], " + "app [write=%llu (direct=%llu, buffered=%llu), mapped=%llu, " + "compr(buffered=%llu, mapped=%llu)], " + "fs [data=%llu, cdata=%llu, node=%llu, meta=%llu, discard=%llu], " "gc [data=%llu, node=%llu], " "cp [data=%llu, node=%llu, meta=%llu], " "app [read=%llu (direct=%llu, buffered=%llu), mapped=%llu], " - "fs [data=%llu, (gc_data=%llu, compr_data=%llu), " + "compr(buffered=%llu, mapped=%llu)], " + "fs [data=%llu, (gc_data=%llu, cdata=%llu), " "node=%llu, meta=%llu]", show_dev(__entry->dev), __entry->app_wio, __entry->app_dio, - __entry->app_bio, __entry->app_mio, __entry->fs_dio, + __entry->app_bio, __entry->app_mio, __entry->app_bcdio, + __entry->app_mcdio, __entry->fs_dio, __entry->fs_cdio, __entry->fs_nio, __entry->fs_mio, __entry->fs_discard, __entry->fs_gc_dio, __entry->fs_gc_nio, __entry->fs_cp_dio, __entry->fs_cp_nio, __entry->fs_cp_mio, __entry->app_rio, __entry->app_drio, __entry->app_brio, - __entry->app_mrio, __entry->fs_drio, __entry->fs_gdrio, + __entry->app_mrio, __entry->app_bcrio, __entry->app_mcrio, + __entry->fs_drio, __entry->fs_gdrio, __entry->fs_cdrio, __entry->fs_nrio, __entry->fs_mrio) ); From 265576181b4afda8c60ae85261f55a8430419884 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Sat, 20 Aug 2022 11:06:00 +0800 Subject: [PATCH 079/401] f2fs: remove gc_urgent_high_limited for cleanup Remove redundant sbi->gc_urgent_high_limited. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 1 - fs/f2fs/gc.c | 8 ++++---- fs/f2fs/sysfs.c | 1 - 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 809419a258ed..6770210aae70 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1731,7 +1731,6 @@ struct f2fs_sb_info { unsigned int gc_mode; /* current GC state */ unsigned int next_victim_seg[2]; /* next segment in victim section */ spinlock_t gc_urgent_high_lock; - bool gc_urgent_high_limited; /* indicates having limited trial count */ unsigned int gc_urgent_high_remaining; /* remaining trial count for GC_URGENT_HIGH */ /* for skip statistic */ diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 2a3816c20f84..fd400d148afb 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -97,10 +97,10 @@ static int gc_thread_func(void *data) */ if (sbi->gc_mode == GC_URGENT_HIGH) { spin_lock(&sbi->gc_urgent_high_lock); - if (sbi->gc_urgent_high_limited && - !sbi->gc_urgent_high_remaining--) { - sbi->gc_urgent_high_limited = false; - sbi->gc_mode = GC_NORMAL; + if (sbi->gc_urgent_high_remaining) { + sbi->gc_urgent_high_remaining--; + if (!sbi->gc_urgent_high_remaining) + sbi->gc_mode = GC_NORMAL; } spin_unlock(&sbi->gc_urgent_high_lock); } diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index eba5fb1629d7..39ebf0ad133a 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -527,7 +527,6 @@ out: if (!strcmp(a->attr.name, "gc_urgent_high_remaining")) { spin_lock(&sbi->gc_urgent_high_lock); - sbi->gc_urgent_high_limited = t != 0; sbi->gc_urgent_high_remaining = t; spin_unlock(&sbi->gc_urgent_high_lock); From 2baedb9f93c42d35016c3c2e3015d67fbcb058b0 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 30 Apr 2022 11:47:40 +0300 Subject: [PATCH 080/401] PCI: qcom-ep: Add MODULE_DEVICE_TABLE Add MODULE_DEVICE_TABLE to enable module autoloading for respective device. Link: https://lore.kernel.org/r/20220430084740.3769925-1-dmitry.baryshkov@linaro.org Fixes: f55fee56a631 ("PCI: qcom-ep: Add Qualcomm PCIe Endpoint controller driver") Signed-off-by: Dmitry Baryshkov Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index ec99116ad05c..4c87167861fd 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -704,6 +704,7 @@ static const struct of_device_id qcom_pcie_ep_match[] = { { .compatible = "qcom,sdx55-pcie-ep", }, { } }; +MODULE_DEVICE_TABLE(of, qcom_pcie_ep_match); static struct platform_driver qcom_pcie_ep_driver = { .probe = qcom_pcie_ep_probe, From c5872d6a04d24b7de095fe446896c35cb7bae465 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 30 Aug 2022 14:14:53 -0700 Subject: [PATCH 081/401] Input: clps711x-keypad - get rid of OF_GPIO dependency There is no such dependency in the driver, but it's implicitly used to have OF property APIs available. Replace that by device property API and get rid of OF_GPIO dependency. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220830182839.47965-1-andriy.shevchenko@linux.intel.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 2 +- drivers/input/keyboard/clps711x-keypad.c | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a20ee693b22b..2c6cef222f9c 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -186,7 +186,7 @@ config KEYBOARD_QT2160 config KEYBOARD_CLPS711X tristate "CLPS711X Keypad support" - depends on OF_GPIO && (ARCH_CLPS711X || COMPILE_TEST) + depends on ARCH_CLPS711X || COMPILE_TEST select INPUT_MATRIXKMAP help Say Y here to enable the matrix keypad on the Cirrus Logic diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index 939c88655fc0..4c1a3e611edd 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c @@ -6,9 +6,11 @@ */ #include +#include #include -#include +#include #include +#include #include #include #include @@ -86,7 +88,6 @@ static int clps711x_keypad_probe(struct platform_device *pdev) { struct clps711x_keypad_data *priv; struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; struct input_dev *input; u32 poll_interval; int i, err; @@ -95,11 +96,11 @@ static int clps711x_keypad_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->syscon = syscon_regmap_lookup_by_phandle(np, "syscon"); + priv->syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); if (IS_ERR(priv->syscon)) return PTR_ERR(priv->syscon); - priv->row_count = of_gpio_named_count(np, "row-gpios"); + priv->row_count = gpiod_count(dev, "row"); if (priv->row_count < 1) return -EINVAL; @@ -119,7 +120,7 @@ static int clps711x_keypad_probe(struct platform_device *pdev) return PTR_ERR(data->desc); } - err = of_property_read_u32(np, "poll-interval", &poll_interval); + err = device_property_read_u32(dev, "poll-interval", &poll_interval); if (err) return err; @@ -143,7 +144,7 @@ static int clps711x_keypad_probe(struct platform_device *pdev) return err; input_set_capability(input, EV_MSC, MSC_SCAN); - if (of_property_read_bool(np, "autorepeat")) + if (device_property_read_bool(dev, "autorepeat")) __set_bit(EV_REP, input->evbit); /* Set all columns to low */ From f8f7f47d576f7f5d44ef9237f356bd6d42002614 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 30 Aug 2022 14:15:18 -0700 Subject: [PATCH 082/401] Input: matrix_keypad - replace of_gpio_named_count() by gpiod_count() As a preparation to unexport of_gpio_named_count(), convert the driver to use gpiod_count() instead. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220830183552.50695-1-andriy.shevchenko@linux.intel.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/matrix_keypad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 30924b57058f..63f078f2bc4a 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -416,9 +416,9 @@ matrix_keypad_parse_dt(struct device *dev) return ERR_PTR(-ENOMEM); } - pdata->num_row_gpios = nrow = of_gpio_named_count(np, "row-gpios"); - pdata->num_col_gpios = ncol = of_gpio_named_count(np, "col-gpios"); - if (nrow <= 0 || ncol <= 0) { + pdata->num_row_gpios = nrow = gpiod_count(dev, "row"); + pdata->num_col_gpios = ncol = gpiod_count(dev, "col"); + if (nrow < 0 || ncol < 0) { dev_err(dev, "number of keypad rows/columns not specified\n"); return ERR_PTR(-EINVAL); } From 9d2b2e83ef277b9c7b8852e8717140daa373ccf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 20:54:10 -0700 Subject: [PATCH 083/401] Input: adp5588-keys - support gpi key events as 'gpio keys' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change replaces the support for GPIs as key event generators. Instead of reporting the events directly, we add a gpio based irqchip so that these events can be consumed by keys defined in the gpio-keys driver (as it's goal is indeed for keys on GPIOs capable of generating interrupts). With this, the gpio-adp5588 driver can also be dropped. The basic idea is that all the pins that are not being used as part of the keymap matrix can be possibly requested as GPIOs by gpio-keys (it's also fine to use these pins as plain interrupts though that's not really the point). Since the gpiochip now also has irqchip capabilities, we should only remove it after we free the device interrupt (otherwise we could, in theory, be handling GPIs interrupts while the gpiochip is concurrently removed). Thus the call 'adp5588_gpio_add()' is moved and since the setup phase also needs to come before making the gpios visible, we also need to move 'adp5588_setup()'. While at it, always select GPIOLIB so that we don't need to use #ifdef guards. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-2-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 2 + drivers/input/keyboard/adp5588-keys.c | 274 +++++++++++++------------- include/linux/platform_data/adp5588.h | 2 - 3 files changed, 144 insertions(+), 134 deletions(-) diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 2c6cef222f9c..e445e760a41a 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -40,6 +40,8 @@ config KEYBOARD_ADP5520 config KEYBOARD_ADP5588 tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander" depends on I2C + select GPIOLIB + select GPIOLIB_IRQCHIP help Say Y here if you want to use a ADP5588/87 attached to your system I2C bus. diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index e2719737360a..f5f7ddfe68be 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -40,21 +40,21 @@ #define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4) #define WA_DELAYED_READOUT_TIME 25 +#define ADP5588_INVALID_HWIRQ (~0UL) + struct adp5588_kpad { struct i2c_client *client; struct input_dev *input; ktime_t irq_time; unsigned long delay; unsigned short keycode[ADP5588_KEYMAPSIZE]; - const struct adp5588_gpi_map *gpimap; - unsigned short gpimapsize; -#ifdef CONFIG_GPIOLIB unsigned char gpiomap[ADP5588_MAXGPIO]; struct gpio_chip gc; struct mutex gpio_lock; /* Protect cached dir, dat_out */ u8 dat_out[3]; u8 dir[3]; -#endif + u8 int_en[3]; + u8 irq_mask[3]; }; static int adp5588_read(struct i2c_client *client, u8 reg) @@ -72,7 +72,6 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) return i2c_smbus_write_byte_data(client, reg, val); } -#ifdef CONFIG_GPIOLIB static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) { struct adp5588_kpad *kpad = gpiochip_get_data(chip); @@ -171,9 +170,6 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad, for (i = 0; i < pdata->cols; i++) pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true; - for (i = 0; i < kpad->gpimapsize; i++) - pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; - for (i = 0; i < ADP5588_MAXGPIO; i++) if (!pin_used[i]) kpad->gpiomap[n_unused++] = i; @@ -196,11 +192,79 @@ static void adp5588_gpio_do_teardown(void *_kpad) dev_warn(&kpad->client->dev, "teardown failed %d\n", error); } +static void adp5588_irq_bus_lock(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct adp5588_kpad *kpad = gpiochip_get_data(gc); + + mutex_lock(&kpad->gpio_lock); +} + +static void adp5588_irq_bus_sync_unlock(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct adp5588_kpad *kpad = gpiochip_get_data(gc); + int i; + + for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { + if (kpad->int_en[i] ^ kpad->irq_mask[i]) { + kpad->int_en[i] = kpad->irq_mask[i]; + adp5588_write(kpad->client, GPI_EM1 + i, kpad->int_en[i]); + } + } + + mutex_unlock(&kpad->gpio_lock); +} + +static void adp5588_irq_mask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct adp5588_kpad *kpad = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long real_irq = kpad->gpiomap[hwirq]; + + kpad->irq_mask[ADP5588_BANK(real_irq)] &= ~ADP5588_BIT(real_irq); + gpiochip_disable_irq(gc, hwirq); +} + +static void adp5588_irq_unmask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct adp5588_kpad *kpad = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long real_irq = kpad->gpiomap[hwirq]; + + gpiochip_enable_irq(gc, hwirq); + kpad->irq_mask[ADP5588_BANK(real_irq)] |= ADP5588_BIT(real_irq); +} + +static int adp5588_irq_set_type(struct irq_data *d, unsigned int type) +{ + if (!(type & IRQ_TYPE_EDGE_BOTH)) + return -EINVAL; + + irq_set_handler_locked(d, handle_edge_irq); + + return 0; +} + +static const struct irq_chip adp5588_irq_chip = { + .name = "adp5588", + .irq_mask = adp5588_irq_mask, + .irq_unmask = adp5588_irq_unmask, + .irq_bus_lock = adp5588_irq_bus_lock, + .irq_bus_sync_unlock = adp5588_irq_bus_sync_unlock, + .irq_set_type = adp5588_irq_set_type, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static int adp5588_gpio_add(struct adp5588_kpad *kpad) { struct device *dev = &kpad->client->dev; const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev); const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; + struct gpio_irq_chip *girq; int i, error; if (!gpio_data) @@ -212,6 +276,7 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) return 0; } + kpad->gc.parent = &kpad->client->dev; kpad->gc.direction_input = adp5588_gpio_direction_input; kpad->gc.direction_output = adp5588_gpio_direction_output; kpad->gc.get = adp5588_gpio_get_value; @@ -223,6 +288,11 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) kpad->gc.owner = THIS_MODULE; kpad->gc.names = gpio_data->names; + girq = &kpad->gc.irq; + gpio_irq_chip_set_chip(girq, &adp5588_irq_chip); + girq->handler = handle_bad_irq; + girq->threaded = true; + mutex_init(&kpad->gpio_lock); error = devm_gpiochip_add_data(dev, &kpad->gc, kpad); @@ -255,35 +325,73 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) return 0; } -#else -static inline int adp5588_gpio_add(struct adp5588_kpad *kpad) +static unsigned long adp5588_gpiomap_get_hwirq(struct device *dev, + const u8 *map, unsigned int gpio, + unsigned int ngpios) { - return 0; + unsigned int hwirq; + + for (hwirq = 0; hwirq < ngpios; hwirq++) + if (map[hwirq] == gpio) + return hwirq; + + /* should never happen */ + dev_warn_ratelimited(dev, "could not find the hwirq for gpio(%u)\n", gpio); + + return ADP5588_INVALID_HWIRQ; +} + +static void adp5588_gpio_irq_handle(struct adp5588_kpad *kpad, int key_val, + int key_press) +{ + unsigned int irq, gpio = key_val - GPI_PIN_BASE, irq_type; + struct i2c_client *client = kpad->client; + struct irq_data *irqd; + unsigned long hwirq; + + hwirq = adp5588_gpiomap_get_hwirq(&client->dev, kpad->gpiomap, + gpio, kpad->gc.ngpio); + if (hwirq == ADP5588_INVALID_HWIRQ) { + dev_err(&client->dev, "Could not get hwirq for key(%u)\n", key_val); + return; + } + + irq = irq_find_mapping(kpad->gc.irq.domain, hwirq); + if (!irq) + return; + + irqd = irq_get_irq_data(irq); + if (!irqd) { + dev_err(&client->dev, "Could not get irq(%u) data\n", irq); + return; + } + + irq_type = irqd_get_trigger_type(irqd); + + /* + * Default is active low which means key_press is asserted on + * the falling edge. + */ + if ((irq_type & IRQ_TYPE_EDGE_RISING && !key_press) || + (irq_type & IRQ_TYPE_EDGE_FALLING && key_press)) + handle_nested_irq(irq); } -#endif static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt) { - int i, j; + int i; for (i = 0; i < ev_cnt; i++) { int key = adp5588_read(kpad->client, Key_EVENTA + i); int key_val = key & KEY_EV_MASK; + int key_press = key & KEY_EV_PRESSED; - if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) { - for (j = 0; j < kpad->gpimapsize; j++) { - if (key_val == kpad->gpimap[j].pin) { - input_report_switch(kpad->input, - kpad->gpimap[j].sw_evt, - key & KEY_EV_PRESSED); - break; - } - } - } else { + if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) + /* gpio line used as IRQ source */ + adp5588_gpio_irq_handle(kpad, key_val, key_press); + else input_report_key(kpad->input, - kpad->keycode[key_val - 1], - key & KEY_EV_PRESSED); - } + kpad->keycode[key_val - 1], key_press); } } @@ -341,7 +449,6 @@ static int adp5588_setup(struct i2c_client *client) dev_get_platdata(&client->dev); const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; int i, ret; - unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); @@ -356,23 +463,6 @@ static int adp5588_setup(struct i2c_client *client) for (i = 0; i < KEYP_MAX_EVENT; i++) ret |= adp5588_read(client, Key_EVENTA); - for (i = 0; i < pdata->gpimapsize; i++) { - unsigned short pin = pdata->gpimap[i].pin; - - if (pin <= GPI_PIN_ROW_END) { - evt_mode1 |= (1 << (pin - GPI_PIN_ROW_BASE)); - } else { - evt_mode2 |= ((1 << (pin - GPI_PIN_COL_BASE)) & 0xFF); - evt_mode3 |= ((1 << (pin - GPI_PIN_COL_BASE)) >> 8); - } - } - - if (pdata->gpimapsize) { - ret |= adp5588_write(client, GPI_EM1, evt_mode1); - ret |= adp5588_write(client, GPI_EM2, evt_mode2); - ret |= adp5588_write(client, GPI_EM3, evt_mode3); - } - if (gpio_data) { for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { int pull_mask = gpio_data->pullup_dis_mask; @@ -399,44 +489,6 @@ static int adp5588_setup(struct i2c_client *client) return 0; } -static void adp5588_report_switch_state(struct adp5588_kpad *kpad) -{ - int gpi_stat1 = adp5588_read(kpad->client, GPIO_DAT_STAT1); - int gpi_stat2 = adp5588_read(kpad->client, GPIO_DAT_STAT2); - int gpi_stat3 = adp5588_read(kpad->client, GPIO_DAT_STAT3); - int gpi_stat_tmp, pin_loc; - int i; - - for (i = 0; i < kpad->gpimapsize; i++) { - unsigned short pin = kpad->gpimap[i].pin; - - if (pin <= GPI_PIN_ROW_END) { - gpi_stat_tmp = gpi_stat1; - pin_loc = pin - GPI_PIN_ROW_BASE; - } else if ((pin - GPI_PIN_COL_BASE) < 8) { - gpi_stat_tmp = gpi_stat2; - pin_loc = pin - GPI_PIN_COL_BASE; - } else { - gpi_stat_tmp = gpi_stat3; - pin_loc = pin - GPI_PIN_COL_BASE - 8; - } - - if (gpi_stat_tmp < 0) { - dev_err(&kpad->client->dev, - "Can't read GPIO_DAT_STAT switch %d default to OFF\n", - pin); - gpi_stat_tmp = 0; - } - - input_report_switch(kpad->input, - kpad->gpimap[i].sw_evt, - !(gpi_stat_tmp & (1 << pin_loc))); - } - - input_sync(kpad->input); -} - - static int adp5588_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -469,37 +521,6 @@ static int adp5588_probe(struct i2c_client *client, return -EINVAL; } - if (!pdata->gpimap && pdata->gpimapsize) { - dev_err(&client->dev, "invalid gpimap from pdata\n"); - return -EINVAL; - } - - if (pdata->gpimapsize > ADP5588_GPIMAPSIZE_MAX) { - dev_err(&client->dev, "invalid gpimapsize\n"); - return -EINVAL; - } - - for (i = 0; i < pdata->gpimapsize; i++) { - unsigned short pin = pdata->gpimap[i].pin; - - if (pin < GPI_PIN_BASE || pin > GPI_PIN_END) { - dev_err(&client->dev, "invalid gpi pin data\n"); - return -EINVAL; - } - - if (pin <= GPI_PIN_ROW_END) { - if (pin - GPI_PIN_ROW_BASE + 1 <= pdata->rows) { - dev_err(&client->dev, "invalid gpi row data\n"); - return -EINVAL; - } - } else { - if (pin - GPI_PIN_COL_BASE + 1 <= pdata->cols) { - dev_err(&client->dev, "invalid gpi col data\n"); - return -EINVAL; - } - } - } - if (!client->irq) { dev_err(&client->dev, "no IRQ?\n"); return -EINVAL; @@ -541,9 +562,6 @@ static int adp5588_probe(struct i2c_client *client, memcpy(kpad->keycode, pdata->keymap, pdata->keymapsize * input->keycodesize); - kpad->gpimap = pdata->gpimap; - kpad->gpimapsize = pdata->gpimapsize; - /* setup input device */ __set_bit(EV_KEY, input->evbit); @@ -555,11 +573,6 @@ static int adp5588_probe(struct i2c_client *client, __set_bit(kpad->keycode[i], input->keybit); __clear_bit(KEY_RESERVED, input->keybit); - if (kpad->gpimapsize) - __set_bit(EV_SW, input->evbit); - for (i = 0; i < kpad->gpimapsize; i++) - __set_bit(kpad->gpimap[i].sw_evt, input->swbit); - error = input_register_device(input); if (error) { dev_err(&client->dev, "unable to register input device: %d\n", @@ -567,6 +580,14 @@ static int adp5588_probe(struct i2c_client *client, return error; } + error = adp5588_setup(client); + if (error) + return error; + + error = adp5588_gpio_add(kpad); + if (error) + return error; + error = devm_request_threaded_irq(&client->dev, client->irq, adp5588_hard_irq, adp5588_thread_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, @@ -577,17 +598,6 @@ static int adp5588_probe(struct i2c_client *client, return error; } - error = adp5588_setup(client); - if (error) - return error; - - if (kpad->gpimapsize) - adp5588_report_switch_state(kpad); - - error = adp5588_gpio_add(kpad); - if (error) - return error; - dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); return 0; } diff --git a/include/linux/platform_data/adp5588.h b/include/linux/platform_data/adp5588.h index 6d3f7d911a92..82170ec8c266 100644 --- a/include/linux/platform_data/adp5588.h +++ b/include/linux/platform_data/adp5588.h @@ -147,8 +147,6 @@ struct adp5588_kpad_platform_data { unsigned en_keylock:1; /* Enable Key Lock feature */ unsigned short unlock_key1; /* Unlock Key 1 */ unsigned short unlock_key2; /* Unlock Key 2 */ - const struct adp5588_gpi_map *gpimap; - unsigned short gpimapsize; const struct adp5588_gpio_platform_data *gpio_data; }; From 5ddc896088b02bcf07ec4f16ae75db43b35b0bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 20:55:47 -0700 Subject: [PATCH 084/401] gpio: gpio-adp5588: drop the driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With commit 9d2b2e83ef27 ("Input: adp5588-keys - support gpi key events as 'gpio keys'") the irchip functionality is directly supported in the input driver as the main goal of these pins is to be used as gpio keys. Hence, this driver can be removed. Signed-off-by: Nuno Sá Acked-by: Bartosz Golaszewski Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-3-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- MAINTAINERS | 1 - drivers/gpio/Kconfig | 14 -- drivers/gpio/Makefile | 1 - drivers/gpio/gpio-adp5588.c | 446 ------------------------------------ 4 files changed, 462 deletions(-) delete mode 100644 drivers/gpio/gpio-adp5588.c diff --git a/MAINTAINERS b/MAINTAINERS index 711bcd4f6269..8404c18e6bcf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -556,7 +556,6 @@ M: Michael Hennerich S: Supported W: http://wiki.analog.com/ADP5588 W: https://ez.analog.com/linux-software-drivers -F: drivers/gpio/gpio-adp5588.c F: drivers/input/keyboard/adp5588-keys.c ADP8860 BACKLIGHT DRIVER (ADP8860/ADP8861/ADP8863) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 0642f579196f..3055ed2e115a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -985,20 +985,6 @@ endmenu menu "I2C GPIO expanders" depends on I2C -config GPIO_ADP5588 - tristate "ADP5588 I2C GPIO expander" - help - This option enables support for 18 GPIOs found - on Analog Devices ADP5588 GPIO Expanders. - -config GPIO_ADP5588_IRQ - bool "Interrupt controller support for ADP5588" - depends on GPIO_ADP5588=y - select GPIOLIB_IRQCHIP - help - Say yes here to enable the adp5588 to be used as an interrupt - controller. It requires the driver to be built in the kernel. - config GPIO_ADNP tristate "Avionic Design N-bit GPIO expander" depends on OF_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index a0985d30f51b..5b890a695f82 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o -obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o obj-$(CONFIG_GPIO_AGGREGATOR) += gpio-aggregator.o obj-$(CONFIG_GPIO_ALTERA_A10SR) += gpio-altera-a10sr.o obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c deleted file mode 100644 index 9b562dbbd733..000000000000 --- a/drivers/gpio/gpio-adp5588.c +++ /dev/null @@ -1,446 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * GPIO Chip driver for Analog Devices - * ADP5588/ADP5587 I/O Expander and QWERTY Keypad Controller - * - * Copyright 2009-2010 Analog Devices Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * Early pre 4.0 Silicon required to delay readout by at least 25ms, - * since the Event Counter Register updated 25ms after the interrupt - * asserted. - */ -#define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4) - -struct adp5588_gpio { - struct i2c_client *client; - struct gpio_chip gpio_chip; - struct mutex lock; /* protect cached dir, dat_out */ - /* protect serialized access to the interrupt controller bus */ - struct mutex irq_lock; - uint8_t dat_out[3]; - uint8_t dir[3]; - uint8_t int_lvl_low[3]; - uint8_t int_lvl_high[3]; - uint8_t int_en[3]; - uint8_t irq_mask[3]; - uint8_t int_input_en[3]; -}; - -static int adp5588_gpio_read(struct i2c_client *client, u8 reg) -{ - int ret = i2c_smbus_read_byte_data(client, reg); - - if (ret < 0) - dev_err(&client->dev, "Read Error\n"); - - return ret; -} - -static int adp5588_gpio_write(struct i2c_client *client, u8 reg, u8 val) -{ - int ret = i2c_smbus_write_byte_data(client, reg, val); - - if (ret < 0) - dev_err(&client->dev, "Write Error\n"); - - return ret; -} - -static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) -{ - struct adp5588_gpio *dev = gpiochip_get_data(chip); - unsigned bank = ADP5588_BANK(off); - unsigned bit = ADP5588_BIT(off); - int val; - - mutex_lock(&dev->lock); - - if (dev->dir[bank] & bit) - val = dev->dat_out[bank]; - else - val = adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + bank); - - mutex_unlock(&dev->lock); - - return !!(val & bit); -} - -static void adp5588_gpio_set_value(struct gpio_chip *chip, - unsigned off, int val) -{ - unsigned bank, bit; - struct adp5588_gpio *dev = gpiochip_get_data(chip); - - bank = ADP5588_BANK(off); - bit = ADP5588_BIT(off); - - mutex_lock(&dev->lock); - if (val) - dev->dat_out[bank] |= bit; - else - dev->dat_out[bank] &= ~bit; - - adp5588_gpio_write(dev->client, GPIO_DAT_OUT1 + bank, - dev->dat_out[bank]); - mutex_unlock(&dev->lock); -} - -static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) -{ - int ret; - unsigned bank; - struct adp5588_gpio *dev = gpiochip_get_data(chip); - - bank = ADP5588_BANK(off); - - mutex_lock(&dev->lock); - dev->dir[bank] &= ~ADP5588_BIT(off); - ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]); - mutex_unlock(&dev->lock); - - return ret; -} - -static int adp5588_gpio_direction_output(struct gpio_chip *chip, - unsigned off, int val) -{ - int ret; - unsigned bank, bit; - struct adp5588_gpio *dev = gpiochip_get_data(chip); - - bank = ADP5588_BANK(off); - bit = ADP5588_BIT(off); - - mutex_lock(&dev->lock); - dev->dir[bank] |= bit; - - if (val) - dev->dat_out[bank] |= bit; - else - dev->dat_out[bank] &= ~bit; - - ret = adp5588_gpio_write(dev->client, GPIO_DAT_OUT1 + bank, - dev->dat_out[bank]); - ret |= adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, - dev->dir[bank]); - mutex_unlock(&dev->lock); - - return ret; -} - -#ifdef CONFIG_GPIO_ADP5588_IRQ - -static void adp5588_irq_bus_lock(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct adp5588_gpio *dev = gpiochip_get_data(gc); - - mutex_lock(&dev->irq_lock); -} - - /* - * genirq core code can issue chip->mask/unmask from atomic context. - * This doesn't work for slow busses where an access needs to sleep. - * bus_sync_unlock() is therefore called outside the atomic context, - * syncs the current irq mask state with the slow external controller - * and unlocks the bus. - */ - -static void adp5588_irq_bus_sync_unlock(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct adp5588_gpio *dev = gpiochip_get_data(gc); - int i; - - for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { - if (dev->int_input_en[i]) { - mutex_lock(&dev->lock); - dev->dir[i] &= ~dev->int_input_en[i]; - dev->int_input_en[i] = 0; - adp5588_gpio_write(dev->client, GPIO_DIR1 + i, - dev->dir[i]); - mutex_unlock(&dev->lock); - } - - if (dev->int_en[i] ^ dev->irq_mask[i]) { - dev->int_en[i] = dev->irq_mask[i]; - adp5588_gpio_write(dev->client, GPI_EM1 + i, - dev->int_en[i]); - } - } - - mutex_unlock(&dev->irq_lock); -} - -static void adp5588_irq_mask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct adp5588_gpio *dev = gpiochip_get_data(gc); - - dev->irq_mask[ADP5588_BANK(d->hwirq)] &= ~ADP5588_BIT(d->hwirq); -} - -static void adp5588_irq_unmask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct adp5588_gpio *dev = gpiochip_get_data(gc); - - dev->irq_mask[ADP5588_BANK(d->hwirq)] |= ADP5588_BIT(d->hwirq); -} - -static int adp5588_irq_set_type(struct irq_data *d, unsigned int type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct adp5588_gpio *dev = gpiochip_get_data(gc); - uint16_t gpio = d->hwirq; - unsigned bank, bit; - - bank = ADP5588_BANK(gpio); - bit = ADP5588_BIT(gpio); - - dev->int_lvl_low[bank] &= ~bit; - dev->int_lvl_high[bank] &= ~bit; - - if (type & IRQ_TYPE_EDGE_BOTH || type & IRQ_TYPE_LEVEL_HIGH) - dev->int_lvl_high[bank] |= bit; - - if (type & IRQ_TYPE_EDGE_BOTH || type & IRQ_TYPE_LEVEL_LOW) - dev->int_lvl_low[bank] |= bit; - - dev->int_input_en[bank] |= bit; - - return 0; -} - -static struct irq_chip adp5588_irq_chip = { - .name = "adp5588", - .irq_mask = adp5588_irq_mask, - .irq_unmask = adp5588_irq_unmask, - .irq_bus_lock = adp5588_irq_bus_lock, - .irq_bus_sync_unlock = adp5588_irq_bus_sync_unlock, - .irq_set_type = adp5588_irq_set_type, -}; - -static irqreturn_t adp5588_irq_handler(int irq, void *devid) -{ - struct adp5588_gpio *dev = devid; - int status = adp5588_gpio_read(dev->client, INT_STAT); - - if (status & ADP5588_KE_INT) { - int ev_cnt = adp5588_gpio_read(dev->client, KEY_LCK_EC_STAT); - - if (ev_cnt > 0) { - int i; - - for (i = 0; i < (ev_cnt & ADP5588_KEC); i++) { - int key = adp5588_gpio_read(dev->client, - Key_EVENTA + i); - /* GPIN events begin at 97, - * bit 7 indicates logic level - */ - int gpio = (key & 0x7f) - 97; - int lvl = key & (1 << 7); - int bank = ADP5588_BANK(gpio); - int bit = ADP5588_BIT(gpio); - - if ((lvl && dev->int_lvl_high[bank] & bit) || - (!lvl && dev->int_lvl_low[bank] & bit)) - handle_nested_irq(irq_find_mapping( - dev->gpio_chip.irq.domain, gpio)); - } - } - } - - adp5588_gpio_write(dev->client, INT_STAT, status); /* Status is W1C */ - - return IRQ_HANDLED; -} - - -static int adp5588_irq_init_hw(struct gpio_chip *gc) -{ - struct adp5588_gpio *dev = gpiochip_get_data(gc); - /* Enable IRQs after registering chip */ - adp5588_gpio_write(dev->client, CFG, - ADP5588_AUTO_INC | ADP5588_INT_CFG | ADP5588_KE_IEN); - - return 0; -} - -static int adp5588_irq_setup(struct adp5588_gpio *dev) -{ - struct i2c_client *client = dev->client; - int ret; - struct adp5588_gpio_platform_data *pdata = - dev_get_platdata(&client->dev); - struct gpio_irq_chip *girq; - - adp5588_gpio_write(client, CFG, ADP5588_AUTO_INC); - adp5588_gpio_write(client, INT_STAT, -1); /* status is W1C */ - - mutex_init(&dev->irq_lock); - - ret = devm_request_threaded_irq(&client->dev, client->irq, - NULL, adp5588_irq_handler, IRQF_ONESHOT - | IRQF_TRIGGER_FALLING | IRQF_SHARED, - dev_name(&client->dev), dev); - if (ret) { - dev_err(&client->dev, "failed to request irq %d\n", - client->irq); - return ret; - } - - /* This will be registered in the call to devm_gpiochip_add_data() */ - girq = &dev->gpio_chip.irq; - girq->chip = &adp5588_irq_chip; - /* This will let us handle the parent IRQ in the driver */ - girq->parent_handler = NULL; - girq->num_parents = 0; - girq->parents = NULL; - girq->first = pdata ? pdata->irq_base : 0; - girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_simple_irq; - girq->init_hw = adp5588_irq_init_hw; - girq->threaded = true; - - return 0; -} - -#else -static int adp5588_irq_setup(struct adp5588_gpio *dev) -{ - struct i2c_client *client = dev->client; - dev_warn(&client->dev, "interrupt support not compiled in\n"); - - return 0; -} - -#endif /* CONFIG_GPIO_ADP5588_IRQ */ - -static int adp5588_gpio_probe(struct i2c_client *client) -{ - struct adp5588_gpio_platform_data *pdata = - dev_get_platdata(&client->dev); - struct adp5588_gpio *dev; - struct gpio_chip *gc; - int ret, i, revid; - unsigned int pullup_dis_mask = 0; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); - return -EIO; - } - - dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->client = client; - - gc = &dev->gpio_chip; - gc->direction_input = adp5588_gpio_direction_input; - gc->direction_output = adp5588_gpio_direction_output; - gc->get = adp5588_gpio_get_value; - gc->set = adp5588_gpio_set_value; - gc->can_sleep = true; - gc->base = -1; - gc->parent = &client->dev; - - if (pdata) { - gc->base = pdata->gpio_start; - gc->names = pdata->names; - pullup_dis_mask = pdata->pullup_dis_mask; - } - - gc->ngpio = ADP5588_MAXGPIO; - gc->label = client->name; - gc->owner = THIS_MODULE; - - mutex_init(&dev->lock); - - ret = adp5588_gpio_read(dev->client, DEV_ID); - if (ret < 0) - return ret; - - revid = ret & ADP5588_DEVICE_ID_MASK; - - for (i = 0, ret = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { - dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i); - dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i); - ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0); - ret |= adp5588_gpio_write(client, GPIO_PULL1 + i, - (pullup_dis_mask >> (8 * i)) & 0xFF); - ret |= adp5588_gpio_write(client, GPIO_INT_EN1 + i, 0); - if (ret) - return ret; - } - - if (client->irq) { - if (WA_DELAYED_READOUT_REVID(revid)) { - dev_warn(&client->dev, "GPIO int not supported\n"); - } else { - ret = adp5588_irq_setup(dev); - if (ret) - return ret; - } - } - - ret = devm_gpiochip_add_data(&client->dev, &dev->gpio_chip, dev); - if (ret) - return ret; - - i2c_set_clientdata(client, dev); - - return 0; -} - -static void adp5588_gpio_remove(struct i2c_client *client) -{ - struct adp5588_gpio *dev = i2c_get_clientdata(client); - - if (dev->client->irq) - free_irq(dev->client->irq, dev); -} - -static const struct i2c_device_id adp5588_gpio_id[] = { - { "adp5588-gpio" }, - {} -}; -MODULE_DEVICE_TABLE(i2c, adp5588_gpio_id); - -static const struct of_device_id adp5588_gpio_of_id[] = { - { .compatible = "adi,adp5588-gpio" }, - {} -}; -MODULE_DEVICE_TABLE(of, adp5588_gpio_of_id); - -static struct i2c_driver adp5588_gpio_driver = { - .driver = { - .name = "adp5588-gpio", - .of_match_table = adp5588_gpio_of_id, - }, - .probe_new = adp5588_gpio_probe, - .remove = adp5588_gpio_remove, - .id_table = adp5588_gpio_id, -}; - -module_i2c_driver(adp5588_gpio_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("GPIO ADP5588 Driver"); -MODULE_LICENSE("GPL"); From e960309ce31865713051854d38740575a6bc0a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 20:58:26 -0700 Subject: [PATCH 085/401] Input: adp5588-keys - bail out on returned error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't continue in code paths after some error is found. It makes no sense to do any other device configuration if a previous one failed. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-4-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/adp5588-keys.c | 56 ++++++++++++++++++--------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index f5f7ddfe68be..2452ea4128b3 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -147,9 +147,13 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, ret = adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, kpad->dat_out[bank]); - ret |= adp5588_write(kpad->client, GPIO_DIR1 + bank, + if (ret) + goto out_unlock; + + ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]); +out_unlock: mutex_unlock(&kpad->gpio_lock); return ret; @@ -451,42 +455,58 @@ static int adp5588_setup(struct i2c_client *client) int i, ret; ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); - ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); - ret |= adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8); + if (ret) + return ret; + + ret = adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); + if (ret) + return ret; + + ret = adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8); + if (ret) + return ret; if (pdata->en_keylock) { - ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); - ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); - ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN); + ret = adp5588_write(client, UNLOCK1, pdata->unlock_key1); + if (ret) + return ret; + + ret = adp5588_write(client, UNLOCK2, pdata->unlock_key2); + if (ret) + return ret; + + ret = adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN); + if (ret) + return ret; } - for (i = 0; i < KEYP_MAX_EVENT; i++) - ret |= adp5588_read(client, Key_EVENTA); + for (i = 0; i < KEYP_MAX_EVENT; i++) { + ret = adp5588_read(client, Key_EVENTA); + if (ret) + return ret; + } if (gpio_data) { for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { int pull_mask = gpio_data->pullup_dis_mask; - ret |= adp5588_write(client, GPIO_PULL1 + i, + ret = adp5588_write(client, GPIO_PULL1 + i, (pull_mask >> (8 * i)) & 0xFF); + if (ret) + return ret; } } - ret |= adp5588_write(client, INT_STAT, + ret = adp5588_write(client, INT_STAT, ADP5588_CMP2_INT | ADP5588_CMP1_INT | ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */ + if (ret) + return ret; - ret |= adp5588_write(client, CFG, ADP5588_INT_CFG | + return adp5588_write(client, CFG, ADP5588_INT_CFG | ADP5588_OVR_FLOW_IEN | ADP5588_KE_IEN); - - if (ret < 0) { - dev_err(&client->dev, "Write Error\n"); - return ret; - } - - return 0; } static int adp5588_probe(struct i2c_client *client, From 6704a86283b7e79ff7ae36d388466428f6672962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 21:00:14 -0700 Subject: [PATCH 086/401] Input: adp5588-keys - add support for fw properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use firmware properties (eg: OF) to get the device specific configuration. This change just replaces the platform data since there was no platform using it and so, it makes no sense having both. Special note to the PULL-UP disable setting that is now supported as part of the gpio subsystem (using 'set_config()' callback). Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-5-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 1 + drivers/input/keyboard/adp5588-keys.c | 395 +++++++++++++++++++------- include/linux/platform_data/adp5588.h | 169 ----------- 3 files changed, 289 insertions(+), 276 deletions(-) delete mode 100644 include/linux/platform_data/adp5588.h diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index e445e760a41a..8b0281c4f3c5 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -42,6 +42,7 @@ config KEYBOARD_ADP5588 depends on I2C select GPIOLIB select GPIOLIB_IRQCHIP + select INPUT_MATRIXKMAP help Say Y here if you want to use a ADP5588/87 attached to your system I2C bus. diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 2452ea4128b3..77d538ed4597 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -13,16 +13,149 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #include #include #include -#include +#define DEV_ID 0x00 /* Device ID */ +#define CFG 0x01 /* Configuration Register1 */ +#define INT_STAT 0x02 /* Interrupt Status Register */ +#define KEY_LCK_EC_STAT 0x03 /* Key Lock and Event Counter Register */ +#define Key_EVENTA 0x04 /* Key Event Register A */ +#define Key_EVENTB 0x05 /* Key Event Register B */ +#define Key_EVENTC 0x06 /* Key Event Register C */ +#define Key_EVENTD 0x07 /* Key Event Register D */ +#define Key_EVENTE 0x08 /* Key Event Register E */ +#define Key_EVENTF 0x09 /* Key Event Register F */ +#define Key_EVENTG 0x0A /* Key Event Register G */ +#define Key_EVENTH 0x0B /* Key Event Register H */ +#define Key_EVENTI 0x0C /* Key Event Register I */ +#define Key_EVENTJ 0x0D /* Key Event Register J */ +#define KP_LCK_TMR 0x0E /* Keypad Lock1 to Lock2 Timer */ +#define UNLOCK1 0x0F /* Unlock Key1 */ +#define UNLOCK2 0x10 /* Unlock Key2 */ +#define GPIO_INT_STAT1 0x11 /* GPIO Interrupt Status */ +#define GPIO_INT_STAT2 0x12 /* GPIO Interrupt Status */ +#define GPIO_INT_STAT3 0x13 /* GPIO Interrupt Status */ +#define GPIO_DAT_STAT1 0x14 /* GPIO Data Status, Read twice to clear */ +#define GPIO_DAT_STAT2 0x15 /* GPIO Data Status, Read twice to clear */ +#define GPIO_DAT_STAT3 0x16 /* GPIO Data Status, Read twice to clear */ +#define GPIO_DAT_OUT1 0x17 /* GPIO DATA OUT */ +#define GPIO_DAT_OUT2 0x18 /* GPIO DATA OUT */ +#define GPIO_DAT_OUT3 0x19 /* GPIO DATA OUT */ +#define GPIO_INT_EN1 0x1A /* GPIO Interrupt Enable */ +#define GPIO_INT_EN2 0x1B /* GPIO Interrupt Enable */ +#define GPIO_INT_EN3 0x1C /* GPIO Interrupt Enable */ +#define KP_GPIO1 0x1D /* Keypad or GPIO Selection */ +#define KP_GPIO2 0x1E /* Keypad or GPIO Selection */ +#define KP_GPIO3 0x1F /* Keypad or GPIO Selection */ +#define GPI_EM1 0x20 /* GPI Event Mode 1 */ +#define GPI_EM2 0x21 /* GPI Event Mode 2 */ +#define GPI_EM3 0x22 /* GPI Event Mode 3 */ +#define GPIO_DIR1 0x23 /* GPIO Data Direction */ +#define GPIO_DIR2 0x24 /* GPIO Data Direction */ +#define GPIO_DIR3 0x25 /* GPIO Data Direction */ +#define GPIO_INT_LVL1 0x26 /* GPIO Edge/Level Detect */ +#define GPIO_INT_LVL2 0x27 /* GPIO Edge/Level Detect */ +#define GPIO_INT_LVL3 0x28 /* GPIO Edge/Level Detect */ +#define Debounce_DIS1 0x29 /* Debounce Disable */ +#define Debounce_DIS2 0x2A /* Debounce Disable */ +#define Debounce_DIS3 0x2B /* Debounce Disable */ +#define GPIO_PULL1 0x2C /* GPIO Pull Disable */ +#define GPIO_PULL2 0x2D /* GPIO Pull Disable */ +#define GPIO_PULL3 0x2E /* GPIO Pull Disable */ +#define CMP_CFG_STAT 0x30 /* Comparator Configuration and Status Register */ +#define CMP_CONFG_SENS1 0x31 /* Sensor1 Comparator Configuration Register */ +#define CMP_CONFG_SENS2 0x32 /* L2 Light Sensor Reference Level, Output Falling for Sensor 1 */ +#define CMP1_LVL2_TRIP 0x33 /* L2 Light Sensor Hysteresis (Active when Output Rising) for Sensor 1 */ +#define CMP1_LVL2_HYS 0x34 /* L3 Light Sensor Reference Level, Output Falling For Sensor 1 */ +#define CMP1_LVL3_TRIP 0x35 /* L3 Light Sensor Hysteresis (Active when Output Rising) For Sensor 1 */ +#define CMP1_LVL3_HYS 0x36 /* Sensor 2 Comparator Configuration Register */ +#define CMP2_LVL2_TRIP 0x37 /* L2 Light Sensor Reference Level, Output Falling for Sensor 2 */ +#define CMP2_LVL2_HYS 0x38 /* L2 Light Sensor Hysteresis (Active when Output Rising) for Sensor 2 */ +#define CMP2_LVL3_TRIP 0x39 /* L3 Light Sensor Reference Level, Output Falling For Sensor 2 */ +#define CMP2_LVL3_HYS 0x3A /* L3 Light Sensor Hysteresis (Active when Output Rising) For Sensor 2 */ +#define CMP1_ADC_DAT_R1 0x3B /* Comparator 1 ADC data Register1 */ +#define CMP1_ADC_DAT_R2 0x3C /* Comparator 1 ADC data Register2 */ +#define CMP2_ADC_DAT_R1 0x3D /* Comparator 2 ADC data Register1 */ +#define CMP2_ADC_DAT_R2 0x3E /* Comparator 2 ADC data Register2 */ + +#define ADP5588_DEVICE_ID_MASK 0xF + + /* Configuration Register1 */ +#define ADP5588_AUTO_INC (1 << 7) +#define ADP5588_GPIEM_CFG (1 << 6) +#define ADP5588_OVR_FLOW_M (1 << 5) +#define ADP5588_INT_CFG (1 << 4) +#define ADP5588_OVR_FLOW_IEN (1 << 3) +#define ADP5588_K_LCK_IM (1 << 2) +#define ADP5588_GPI_IEN (1 << 1) +#define ADP5588_KE_IEN (1 << 0) + +/* Interrupt Status Register */ +#define ADP5588_CMP2_INT (1 << 5) +#define ADP5588_CMP1_INT (1 << 4) +#define ADP5588_OVR_FLOW_INT (1 << 3) +#define ADP5588_K_LCK_INT (1 << 2) +#define ADP5588_GPI_INT (1 << 1) +#define ADP5588_KE_INT (1 << 0) + +/* Key Lock and Event Counter Register */ +#define ADP5588_K_LCK_EN (1 << 6) +#define ADP5588_LCK21 0x30 +#define ADP5588_KEC 0xF + +#define ADP5588_MAXGPIO 18 +#define ADP5588_BANK(offs) ((offs) >> 3) +#define ADP5588_BIT(offs) (1u << ((offs) & 0x7)) + +/* Put one of these structures in i2c_board_info platform_data */ + +/* + * 128 so it fits matrix-keymap maximum number of keys when the full + * 10cols * 8rows are used. + */ +#define ADP5588_KEYMAPSIZE 128 + +#define GPI_PIN_ROW0 97 +#define GPI_PIN_ROW1 98 +#define GPI_PIN_ROW2 99 +#define GPI_PIN_ROW3 100 +#define GPI_PIN_ROW4 101 +#define GPI_PIN_ROW5 102 +#define GPI_PIN_ROW6 103 +#define GPI_PIN_ROW7 104 +#define GPI_PIN_COL0 105 +#define GPI_PIN_COL1 106 +#define GPI_PIN_COL2 107 +#define GPI_PIN_COL3 108 +#define GPI_PIN_COL4 109 +#define GPI_PIN_COL5 110 +#define GPI_PIN_COL6 111 +#define GPI_PIN_COL7 112 +#define GPI_PIN_COL8 113 +#define GPI_PIN_COL9 114 + +#define GPI_PIN_ROW_BASE GPI_PIN_ROW0 +#define GPI_PIN_ROW_END GPI_PIN_ROW7 +#define GPI_PIN_COL_BASE GPI_PIN_COL0 +#define GPI_PIN_COL_END GPI_PIN_COL9 + +#define GPI_PIN_BASE GPI_PIN_ROW_BASE +#define GPI_PIN_END GPI_PIN_COL_END + +#define ADP5588_ROWS_MAX (GPI_PIN_ROW7 - GPI_PIN_ROW0 + 1) +#define ADP5588_COLS_MAX (GPI_PIN_COL9 - GPI_PIN_COL0 + 1) + +#define ADP5588_GPIMAPSIZE_MAX (GPI_PIN_END - GPI_PIN_BASE + 1) /* Key Event Register xy */ #define KEY_EV_PRESSED (1 << 7) @@ -47,6 +180,11 @@ struct adp5588_kpad { struct input_dev *input; ktime_t irq_time; unsigned long delay; + u32 row_shift; + u32 rows; + u32 cols; + u32 unlock_keys[2]; + int nkeys_unlock; unsigned short keycode[ADP5588_KEYMAPSIZE]; unsigned char gpiomap[ADP5588_MAXGPIO]; struct gpio_chip gc; @@ -55,6 +193,7 @@ struct adp5588_kpad { u8 dir[3]; u8 int_en[3]; u8 irq_mask[3]; + u8 pull_dis[3]; }; static int adp5588_read(struct i2c_client *client, u8 reg) @@ -111,6 +250,41 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, mutex_unlock(&kpad->gpio_lock); } +static int adp5588_gpio_set_config(struct gpio_chip *chip, unsigned int off, + unsigned long config) +{ + struct adp5588_kpad *kpad = gpiochip_get_data(chip); + unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + bool pull_disable; + int ret; + + switch (pinconf_to_config_param(config)) { + case PIN_CONFIG_BIAS_PULL_UP: + pull_disable = false; + break; + case PIN_CONFIG_BIAS_DISABLE: + pull_disable = true; + break; + default: + return -ENOTSUPP; + } + + mutex_lock(&kpad->gpio_lock); + + if (pull_disable) + kpad->pull_dis[bank] |= bit; + else + kpad->pull_dis[bank] &= bit; + + ret = adp5588_write(kpad->client, GPIO_PULL1 + bank, + kpad->pull_dis[bank]); + + mutex_unlock(&kpad->gpio_lock); + + return ret; +} + static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) { struct adp5588_kpad *kpad = gpiochip_get_data(chip); @@ -159,8 +333,7 @@ out_unlock: return ret; } -static int adp5588_build_gpiomap(struct adp5588_kpad *kpad, - const struct adp5588_kpad_platform_data *pdata) +static int adp5588_build_gpiomap(struct adp5588_kpad *kpad) { bool pin_used[ADP5588_MAXGPIO]; int n_unused = 0; @@ -168,10 +341,10 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad, memset(pin_used, 0, sizeof(pin_used)); - for (i = 0; i < pdata->rows; i++) + for (i = 0; i < kpad->rows; i++) pin_used[i] = true; - for (i = 0; i < pdata->cols; i++) + for (i = 0; i < kpad->cols; i++) pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true; for (i = 0; i < ADP5588_MAXGPIO; i++) @@ -181,21 +354,6 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad, return n_unused; } -static void adp5588_gpio_do_teardown(void *_kpad) -{ - struct adp5588_kpad *kpad = _kpad; - struct device *dev = &kpad->client->dev; - const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev); - const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; - int error; - - error = gpio_data->teardown(kpad->client, - kpad->gc.base, kpad->gc.ngpio, - gpio_data->context); - if (error) - dev_warn(&kpad->client->dev, "teardown failed %d\n", error); -} - static void adp5588_irq_bus_lock(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); @@ -266,15 +424,10 @@ static const struct irq_chip adp5588_irq_chip = { static int adp5588_gpio_add(struct adp5588_kpad *kpad) { struct device *dev = &kpad->client->dev; - const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev); - const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; struct gpio_irq_chip *girq; int i, error; - if (!gpio_data) - return 0; - - kpad->gc.ngpio = adp5588_build_gpiomap(kpad, pdata); + kpad->gc.ngpio = adp5588_build_gpiomap(kpad); if (kpad->gc.ngpio == 0) { dev_info(dev, "No unused gpios left to export\n"); return 0; @@ -285,12 +438,12 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) kpad->gc.direction_output = adp5588_gpio_direction_output; kpad->gc.get = adp5588_gpio_get_value; kpad->gc.set = adp5588_gpio_set_value; + kpad->gc.set_config = adp5588_gpio_set_config; kpad->gc.can_sleep = 1; - kpad->gc.base = gpio_data->gpio_start; + kpad->gc.base = -1; kpad->gc.label = kpad->client->name; kpad->gc.owner = THIS_MODULE; - kpad->gc.names = gpio_data->names; girq = &kpad->gc.irq; gpio_irq_chip_set_chip(girq, &adp5588_irq_chip); @@ -309,21 +462,7 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) kpad->dat_out[i] = adp5588_read(kpad->client, GPIO_DAT_OUT1 + i); kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); - } - - if (gpio_data->setup) { - error = gpio_data->setup(kpad->client, - kpad->gc.base, kpad->gc.ngpio, - gpio_data->context); - if (error) - dev_warn(dev, "setup failed: %d\n", error); - } - - if (gpio_data->teardown) { - error = devm_add_action(dev, adp5588_gpio_do_teardown, kpad); - if (error) - dev_warn(dev, "failed to schedule teardown: %d\n", - error); + kpad->pull_dis[i] = adp5588_read(kpad->client, GPIO_PULL1 + i); } return 0; @@ -390,12 +529,21 @@ static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt) int key_val = key & KEY_EV_MASK; int key_press = key & KEY_EV_PRESSED; - if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) + if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) { /* gpio line used as IRQ source */ adp5588_gpio_irq_handle(kpad, key_val, key_press); - else + } else { + int row = (key_val - 1) / ADP5588_COLS_MAX; + int col = (key_val - 1) % ADP5588_COLS_MAX; + int code = MATRIX_SCAN_CODE(row, col, kpad->row_shift); + + dev_dbg_ratelimited(&kpad->client->dev, + "report key(%d) r(%d) c(%d) code(%d)\n", + key_val, row, col, kpad->keycode[code]); + input_report_key(kpad->input, - kpad->keycode[key_val - 1], key_press); + kpad->keycode[code], key_press); + } } } @@ -447,34 +595,30 @@ static irqreturn_t adp5588_thread_irq(int irq, void *handle) return IRQ_HANDLED; } -static int adp5588_setup(struct i2c_client *client) +static int adp5588_setup(struct adp5588_kpad *kpad) { - const struct adp5588_kpad_platform_data *pdata = - dev_get_platdata(&client->dev); - const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; + struct i2c_client *client = kpad->client; int i, ret; - ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); + ret = adp5588_write(client, KP_GPIO1, KP_SEL(kpad->rows)); if (ret) return ret; - ret = adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); + ret = adp5588_write(client, KP_GPIO2, KP_SEL(kpad->cols) & 0xFF); if (ret) return ret; - ret = adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8); + ret = adp5588_write(client, KP_GPIO3, KP_SEL(kpad->cols) >> 8); if (ret) return ret; - if (pdata->en_keylock) { - ret = adp5588_write(client, UNLOCK1, pdata->unlock_key1); - if (ret) - return ret; - - ret = adp5588_write(client, UNLOCK2, pdata->unlock_key2); + for (i = 0; i < kpad->nkeys_unlock; i++) { + ret = adp5588_write(client, UNLOCK1 + i, kpad->unlock_keys[i]); if (ret) return ret; + } + if (kpad->nkeys_unlock) { ret = adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN); if (ret) return ret; @@ -486,17 +630,6 @@ static int adp5588_setup(struct i2c_client *client) return ret; } - if (gpio_data) { - for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { - int pull_mask = gpio_data->pullup_dis_mask; - - ret = adp5588_write(client, GPIO_PULL1 + i, - (pull_mask >> (8 * i)) & 0xFF); - if (ret) - return ret; - } - } - ret = adp5588_write(client, INT_STAT, ADP5588_CMP2_INT | ADP5588_CMP1_INT | ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | @@ -509,15 +642,84 @@ static int adp5588_setup(struct i2c_client *client) ADP5588_KE_IEN); } +static int adp5588_fw_parse(struct adp5588_kpad *kpad) +{ + struct i2c_client *client = kpad->client; + int ret, i; + + ret = matrix_keypad_parse_properties(&client->dev, &kpad->rows, + &kpad->cols); + if (ret) + return ret; + + if (kpad->rows > ADP5588_ROWS_MAX || kpad->cols > ADP5588_COLS_MAX) { + dev_err(&client->dev, "Invalid nr of rows(%u) or cols(%u)\n", + kpad->rows, kpad->cols); + return -EINVAL; + } + + ret = matrix_keypad_build_keymap(NULL, NULL, kpad->rows, kpad->cols, + kpad->keycode, kpad->input); + if (ret) + return ret; + + kpad->row_shift = get_count_order(kpad->cols); + + if (device_property_read_bool(&client->dev, "autorepeat")) + __set_bit(EV_REP, kpad->input->evbit); + + kpad->nkeys_unlock = device_property_count_u32(&client->dev, + "adi,unlock-keys"); + if (kpad->nkeys_unlock <= 0) { + /* so that we don't end up enabling key lock */ + kpad->nkeys_unlock = 0; + return 0; + } + + if (kpad->nkeys_unlock > ARRAY_SIZE(kpad->unlock_keys)) { + dev_err(&client->dev, "number of unlock keys(%d) > (%zu)\n", + kpad->nkeys_unlock, ARRAY_SIZE(kpad->unlock_keys)); + return -EINVAL; + } + + ret = device_property_read_u32_array(&client->dev, "adi,unlock-keys", + kpad->unlock_keys, + kpad->nkeys_unlock); + if (ret) + return ret; + + for (i = 0; i < kpad->nkeys_unlock; i++) { + /* + * Even though it should be possible (as stated in the datasheet) + * to use GPIs (which are part of the keys event) as unlock keys, + * it was not working at all and was leading to overflow events + * at some point. Hence, for now, let's just allow keys which are + * part of keypad matrix to be used and if a reliable way of + * using GPIs is found, this condition can be removed/lightened. + */ + if (kpad->unlock_keys[i] >= kpad->cols * kpad->rows) { + dev_err(&client->dev, "Invalid unlock key(%d)\n", + kpad->unlock_keys[i]); + return -EINVAL; + } + + /* + * Firmware properties keys start from 0 but on the device they + * start from 1. + */ + kpad->unlock_keys[i] += 1; + } + + return 0; +} + static int adp5588_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adp5588_kpad *kpad; - const struct adp5588_kpad_platform_data *pdata = - dev_get_platdata(&client->dev); struct input_dev *input; unsigned int revid; - int ret, i; + int ret; int error; if (!i2c_check_functionality(client->adapter, @@ -526,21 +728,6 @@ static int adp5588_probe(struct i2c_client *client, return -EIO; } - if (!pdata) { - dev_err(&client->dev, "no platform data?\n"); - return -EINVAL; - } - - if (!pdata->rows || !pdata->cols || !pdata->keymap) { - dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); - return -EINVAL; - } - - if (pdata->keymapsize != ADP5588_KEYMAPSIZE) { - dev_err(&client->dev, "invalid keymapsize\n"); - return -EINVAL; - } - if (!client->irq) { dev_err(&client->dev, "no IRQ?\n"); return -EINVAL; @@ -557,6 +744,10 @@ static int adp5588_probe(struct i2c_client *client, kpad->client = client; kpad->input = input; + error = adp5588_fw_parse(kpad); + if (error) + return error; + ret = adp5588_read(client, DEV_ID); if (ret < 0) return ret; @@ -575,24 +766,6 @@ static int adp5588_probe(struct i2c_client *client, input->id.product = 0x0001; input->id.version = revid; - input->keycodesize = sizeof(kpad->keycode[0]); - input->keycodemax = pdata->keymapsize; - input->keycode = kpad->keycode; - - memcpy(kpad->keycode, pdata->keymap, - pdata->keymapsize * input->keycodesize); - - /* setup input device */ - __set_bit(EV_KEY, input->evbit); - - if (pdata->repeat) - __set_bit(EV_REP, input->evbit); - - for (i = 0; i < input->keycodemax; i++) - if (kpad->keycode[i] <= KEY_MAX) - __set_bit(kpad->keycode[i], input->keybit); - __clear_bit(KEY_RESERVED, input->keybit); - error = input_register_device(input); if (error) { dev_err(&client->dev, "unable to register input device: %d\n", @@ -600,7 +773,7 @@ static int adp5588_probe(struct i2c_client *client, return error; } - error = adp5588_setup(client); + error = adp5588_setup(kpad); if (error) return error; @@ -656,9 +829,17 @@ static const struct i2c_device_id adp5588_id[] = { }; MODULE_DEVICE_TABLE(i2c, adp5588_id); +static const struct of_device_id adp5588_of_match[] = { + { .compatible = "adi,adp5588" }, + { .compatible = "adi,adp5587" }, + {} +}; +MODULE_DEVICE_TABLE(of, adp5588_of_match); + static struct i2c_driver adp5588_driver = { .driver = { .name = KBUILD_MODNAME, + .of_match_table = adp5588_of_match, .pm = &adp5588_dev_pm_ops, }, .probe = adp5588_probe, diff --git a/include/linux/platform_data/adp5588.h b/include/linux/platform_data/adp5588.h deleted file mode 100644 index 82170ec8c266..000000000000 --- a/include/linux/platform_data/adp5588.h +++ /dev/null @@ -1,169 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller - * - * Copyright 2009-2010 Analog Devices Inc. - */ - -#ifndef _ADP5588_H -#define _ADP5588_H - -#define DEV_ID 0x00 /* Device ID */ -#define CFG 0x01 /* Configuration Register1 */ -#define INT_STAT 0x02 /* Interrupt Status Register */ -#define KEY_LCK_EC_STAT 0x03 /* Key Lock and Event Counter Register */ -#define Key_EVENTA 0x04 /* Key Event Register A */ -#define Key_EVENTB 0x05 /* Key Event Register B */ -#define Key_EVENTC 0x06 /* Key Event Register C */ -#define Key_EVENTD 0x07 /* Key Event Register D */ -#define Key_EVENTE 0x08 /* Key Event Register E */ -#define Key_EVENTF 0x09 /* Key Event Register F */ -#define Key_EVENTG 0x0A /* Key Event Register G */ -#define Key_EVENTH 0x0B /* Key Event Register H */ -#define Key_EVENTI 0x0C /* Key Event Register I */ -#define Key_EVENTJ 0x0D /* Key Event Register J */ -#define KP_LCK_TMR 0x0E /* Keypad Lock1 to Lock2 Timer */ -#define UNLOCK1 0x0F /* Unlock Key1 */ -#define UNLOCK2 0x10 /* Unlock Key2 */ -#define GPIO_INT_STAT1 0x11 /* GPIO Interrupt Status */ -#define GPIO_INT_STAT2 0x12 /* GPIO Interrupt Status */ -#define GPIO_INT_STAT3 0x13 /* GPIO Interrupt Status */ -#define GPIO_DAT_STAT1 0x14 /* GPIO Data Status, Read twice to clear */ -#define GPIO_DAT_STAT2 0x15 /* GPIO Data Status, Read twice to clear */ -#define GPIO_DAT_STAT3 0x16 /* GPIO Data Status, Read twice to clear */ -#define GPIO_DAT_OUT1 0x17 /* GPIO DATA OUT */ -#define GPIO_DAT_OUT2 0x18 /* GPIO DATA OUT */ -#define GPIO_DAT_OUT3 0x19 /* GPIO DATA OUT */ -#define GPIO_INT_EN1 0x1A /* GPIO Interrupt Enable */ -#define GPIO_INT_EN2 0x1B /* GPIO Interrupt Enable */ -#define GPIO_INT_EN3 0x1C /* GPIO Interrupt Enable */ -#define KP_GPIO1 0x1D /* Keypad or GPIO Selection */ -#define KP_GPIO2 0x1E /* Keypad or GPIO Selection */ -#define KP_GPIO3 0x1F /* Keypad or GPIO Selection */ -#define GPI_EM1 0x20 /* GPI Event Mode 1 */ -#define GPI_EM2 0x21 /* GPI Event Mode 2 */ -#define GPI_EM3 0x22 /* GPI Event Mode 3 */ -#define GPIO_DIR1 0x23 /* GPIO Data Direction */ -#define GPIO_DIR2 0x24 /* GPIO Data Direction */ -#define GPIO_DIR3 0x25 /* GPIO Data Direction */ -#define GPIO_INT_LVL1 0x26 /* GPIO Edge/Level Detect */ -#define GPIO_INT_LVL2 0x27 /* GPIO Edge/Level Detect */ -#define GPIO_INT_LVL3 0x28 /* GPIO Edge/Level Detect */ -#define Debounce_DIS1 0x29 /* Debounce Disable */ -#define Debounce_DIS2 0x2A /* Debounce Disable */ -#define Debounce_DIS3 0x2B /* Debounce Disable */ -#define GPIO_PULL1 0x2C /* GPIO Pull Disable */ -#define GPIO_PULL2 0x2D /* GPIO Pull Disable */ -#define GPIO_PULL3 0x2E /* GPIO Pull Disable */ -#define CMP_CFG_STAT 0x30 /* Comparator Configuration and Status Register */ -#define CMP_CONFG_SENS1 0x31 /* Sensor1 Comparator Configuration Register */ -#define CMP_CONFG_SENS2 0x32 /* L2 Light Sensor Reference Level, Output Falling for Sensor 1 */ -#define CMP1_LVL2_TRIP 0x33 /* L2 Light Sensor Hysteresis (Active when Output Rising) for Sensor 1 */ -#define CMP1_LVL2_HYS 0x34 /* L3 Light Sensor Reference Level, Output Falling For Sensor 1 */ -#define CMP1_LVL3_TRIP 0x35 /* L3 Light Sensor Hysteresis (Active when Output Rising) For Sensor 1 */ -#define CMP1_LVL3_HYS 0x36 /* Sensor 2 Comparator Configuration Register */ -#define CMP2_LVL2_TRIP 0x37 /* L2 Light Sensor Reference Level, Output Falling for Sensor 2 */ -#define CMP2_LVL2_HYS 0x38 /* L2 Light Sensor Hysteresis (Active when Output Rising) for Sensor 2 */ -#define CMP2_LVL3_TRIP 0x39 /* L3 Light Sensor Reference Level, Output Falling For Sensor 2 */ -#define CMP2_LVL3_HYS 0x3A /* L3 Light Sensor Hysteresis (Active when Output Rising) For Sensor 2 */ -#define CMP1_ADC_DAT_R1 0x3B /* Comparator 1 ADC data Register1 */ -#define CMP1_ADC_DAT_R2 0x3C /* Comparator 1 ADC data Register2 */ -#define CMP2_ADC_DAT_R1 0x3D /* Comparator 2 ADC data Register1 */ -#define CMP2_ADC_DAT_R2 0x3E /* Comparator 2 ADC data Register2 */ - -#define ADP5588_DEVICE_ID_MASK 0xF - - /* Configuration Register1 */ -#define ADP5588_AUTO_INC (1 << 7) -#define ADP5588_GPIEM_CFG (1 << 6) -#define ADP5588_OVR_FLOW_M (1 << 5) -#define ADP5588_INT_CFG (1 << 4) -#define ADP5588_OVR_FLOW_IEN (1 << 3) -#define ADP5588_K_LCK_IM (1 << 2) -#define ADP5588_GPI_IEN (1 << 1) -#define ADP5588_KE_IEN (1 << 0) - -/* Interrupt Status Register */ -#define ADP5588_CMP2_INT (1 << 5) -#define ADP5588_CMP1_INT (1 << 4) -#define ADP5588_OVR_FLOW_INT (1 << 3) -#define ADP5588_K_LCK_INT (1 << 2) -#define ADP5588_GPI_INT (1 << 1) -#define ADP5588_KE_INT (1 << 0) - -/* Key Lock and Event Counter Register */ -#define ADP5588_K_LCK_EN (1 << 6) -#define ADP5588_LCK21 0x30 -#define ADP5588_KEC 0xF - -#define ADP5588_MAXGPIO 18 -#define ADP5588_BANK(offs) ((offs) >> 3) -#define ADP5588_BIT(offs) (1u << ((offs) & 0x7)) - -/* Put one of these structures in i2c_board_info platform_data */ - -#define ADP5588_KEYMAPSIZE 80 - -#define GPI_PIN_ROW0 97 -#define GPI_PIN_ROW1 98 -#define GPI_PIN_ROW2 99 -#define GPI_PIN_ROW3 100 -#define GPI_PIN_ROW4 101 -#define GPI_PIN_ROW5 102 -#define GPI_PIN_ROW6 103 -#define GPI_PIN_ROW7 104 -#define GPI_PIN_COL0 105 -#define GPI_PIN_COL1 106 -#define GPI_PIN_COL2 107 -#define GPI_PIN_COL3 108 -#define GPI_PIN_COL4 109 -#define GPI_PIN_COL5 110 -#define GPI_PIN_COL6 111 -#define GPI_PIN_COL7 112 -#define GPI_PIN_COL8 113 -#define GPI_PIN_COL9 114 - -#define GPI_PIN_ROW_BASE GPI_PIN_ROW0 -#define GPI_PIN_ROW_END GPI_PIN_ROW7 -#define GPI_PIN_COL_BASE GPI_PIN_COL0 -#define GPI_PIN_COL_END GPI_PIN_COL9 - -#define GPI_PIN_BASE GPI_PIN_ROW_BASE -#define GPI_PIN_END GPI_PIN_COL_END - -#define ADP5588_GPIMAPSIZE_MAX (GPI_PIN_END - GPI_PIN_BASE + 1) - -struct adp5588_gpi_map { - unsigned short pin; - unsigned short sw_evt; -}; - -struct adp5588_kpad_platform_data { - int rows; /* Number of rows */ - int cols; /* Number of columns */ - const unsigned short *keymap; /* Pointer to keymap */ - unsigned short keymapsize; /* Keymap size */ - unsigned repeat:1; /* Enable key repeat */ - unsigned en_keylock:1; /* Enable Key Lock feature */ - unsigned short unlock_key1; /* Unlock Key 1 */ - unsigned short unlock_key2; /* Unlock Key 2 */ - const struct adp5588_gpio_platform_data *gpio_data; -}; - -struct i2c_client; /* forward declaration */ - -struct adp5588_gpio_platform_data { - int gpio_start; /* GPIO Chip base # */ - const char *const *names; - unsigned irq_base; /* interrupt base # */ - unsigned pullup_dis_mask; /* Pull-Up Disable Mask */ - int (*setup)(struct i2c_client *client, - unsigned gpio, unsigned ngpio, - void *context); - int (*teardown)(struct i2c_client *client, - unsigned gpio, unsigned ngpio, - void *context); - void *context; -}; - -#endif From 81ce5b77417ac9623d1c6270a2f75a0a3a734d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 21:08:18 -0700 Subject: [PATCH 087/401] dt-bindings: input: adp5588: add bindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add device tree bindings for the adp5588-keys driver. Signed-off-by: Nuno Sá Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220829131553.690063-6-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- .../bindings/input/adi,adp5588.yaml | 111 ++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 112 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/adi,adp5588.yaml diff --git a/Documentation/devicetree/bindings/input/adi,adp5588.yaml b/Documentation/devicetree/bindings/input/adi,adp5588.yaml new file mode 100644 index 000000000000..26ea66834ae2 --- /dev/null +++ b/Documentation/devicetree/bindings/input/adi,adp5588.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/adi,adp5588.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices ADP5588 Keypad Controller + +maintainers: + - Nuno Sá + +description: | + Analog Devices Mobile I/O Expander and QWERTY Keypad Controller + https://www.analog.com/media/en/technical-documentation/data-sheets/ADP5588.pdf + +allOf: + - $ref: matrix-keymap.yaml# + - $ref: input.yaml# + +properties: + compatible: + enum: + - adi,adp5587 + - adi,adp5588 + + reg: + maxItems: 1 + + vcc-supply: + description: Supply Voltage Input + + reset-gpios: + description: + If specified, it will be asserted during driver probe. As the line is + active low, it should be marked GPIO_ACTIVE_LOW. + maxItems: 1 + + interrupts: + maxItems: 1 + + gpio-controller: + description: + This property applies if either keypad,num-rows lower than 8 or + keypad,num-columns lower than 10. + + '#gpio-cells': + const: 2 + + interrupt-controller: + description: + This property applies if either keypad,num-rows lower than 8 or + keypad,num-columns lower than 10. + + '#interrupt-cells': + const: 2 + + adi,unlock-keys: + description: + Specifies a maximum of 2 keys that can be used to unlock the keypad. + If this property is set, the keyboard will be locked and only unlocked + after these keys are pressed. If only one key is set, a double click is + needed to unlock the keypad. The value of this property cannot be bigger + or equal than keypad,num-rows * keypad,num-columns. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 2 + +required: + - compatible + - reg + - interrupts + - keypad,num-rows + - keypad,num-columns + - linux,keymap + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + keys@34 { + compatible = "adi,adp5588"; + reg = <0x34>; + + vcc-supply = <&vcc>; + interrupts = <21 IRQ_TYPE_EDGE_FALLING>; + interrupt-parent = <&gpio>; + reset-gpios = <&gpio 20 GPIO_ACTIVE_LOW>; + + keypad,num-rows = <1>; + keypad,num-columns = <9>; + linux,keymap = < + MATRIX_KEY(0x00, 0x00, KEY_1) + MATRIX_KEY(0x00, 0x01, KEY_2) + MATRIX_KEY(0x00, 0x02, KEY_3) + MATRIX_KEY(0x00, 0x03, KEY_4) + MATRIX_KEY(0x00, 0x04, KEY_5) + MATRIX_KEY(0x00, 0x05, KEY_6) + MATRIX_KEY(0x00, 0x06, KEY_7) + MATRIX_KEY(0x00, 0x07, KEY_8) + MATRIX_KEY(0x00, 0x08, KEY_9) + >; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 8404c18e6bcf..aa71df8b699b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -556,6 +556,7 @@ M: Michael Hennerich S: Supported W: http://wiki.analog.com/ADP5588 W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/input/adi,adp5588.yaml F: drivers/input/keyboard/adp5588-keys.c ADP8860 BACKLIGHT DRIVER (ADP8860/ADP8861/ADP8863) From 0063aecc61e1beec09611d830f4aae5a90a96c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 21:09:32 -0700 Subject: [PATCH 088/401] Input: adp5588-keys - do not check for irq presence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no need for an extra check for 'client-irq'. Just let it fail when calling 'request_irq()'. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-7-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/adp5588-keys.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 77d538ed4597..9ff35910fc5d 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -728,11 +728,6 @@ static int adp5588_probe(struct i2c_client *client, return -EIO; } - if (!client->irq) { - dev_err(&client->dev, "no IRQ?\n"); - return -EINVAL; - } - kpad = devm_kzalloc(&client->dev, sizeof(*kpad), GFP_KERNEL); if (!kpad) return -ENOMEM; From e22d21d31f5d0ade2fa80c44d615ee488b723063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 21:09:54 -0700 Subject: [PATCH 089/401] Input: adp5588-keys - fix coding style warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just some code cleanup regarding coding style. With the introduction of the bits.h macros changes in the code are indeed introduced. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-8-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/adp5588-keys.c | 98 +++++++++++++-------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 9ff35910fc5d..565123e5894b 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -8,6 +8,7 @@ * Copyright (C) 2008-2010 Analog Devices Inc. */ +#include #include #include #include @@ -29,16 +30,16 @@ #define CFG 0x01 /* Configuration Register1 */ #define INT_STAT 0x02 /* Interrupt Status Register */ #define KEY_LCK_EC_STAT 0x03 /* Key Lock and Event Counter Register */ -#define Key_EVENTA 0x04 /* Key Event Register A */ -#define Key_EVENTB 0x05 /* Key Event Register B */ -#define Key_EVENTC 0x06 /* Key Event Register C */ -#define Key_EVENTD 0x07 /* Key Event Register D */ -#define Key_EVENTE 0x08 /* Key Event Register E */ -#define Key_EVENTF 0x09 /* Key Event Register F */ -#define Key_EVENTG 0x0A /* Key Event Register G */ -#define Key_EVENTH 0x0B /* Key Event Register H */ -#define Key_EVENTI 0x0C /* Key Event Register I */ -#define Key_EVENTJ 0x0D /* Key Event Register J */ +#define KEY_EVENTA 0x04 /* Key Event Register A */ +#define KEY_EVENTB 0x05 /* Key Event Register B */ +#define KEY_EVENTC 0x06 /* Key Event Register C */ +#define KEY_EVENTD 0x07 /* Key Event Register D */ +#define KEY_EVENTE 0x08 /* Key Event Register E */ +#define KEY_EVENTF 0x09 /* Key Event Register F */ +#define KEY_EVENTG 0x0A /* Key Event Register G */ +#define KEY_EVENTH 0x0B /* Key Event Register H */ +#define KEY_EVENTI 0x0C /* Key Event Register I */ +#define KEY_EVENTJ 0x0D /* Key Event Register J */ #define KP_LCK_TMR 0x0E /* Keypad Lock1 to Lock2 Timer */ #define UNLOCK1 0x0F /* Unlock Key1 */ #define UNLOCK2 0x10 /* Unlock Key2 */ @@ -66,9 +67,9 @@ #define GPIO_INT_LVL1 0x26 /* GPIO Edge/Level Detect */ #define GPIO_INT_LVL2 0x27 /* GPIO Edge/Level Detect */ #define GPIO_INT_LVL3 0x28 /* GPIO Edge/Level Detect */ -#define Debounce_DIS1 0x29 /* Debounce Disable */ -#define Debounce_DIS2 0x2A /* Debounce Disable */ -#define Debounce_DIS3 0x2B /* Debounce Disable */ +#define DEBOUNCE_DIS1 0x29 /* Debounce Disable */ +#define DEBOUNCE_DIS2 0x2A /* Debounce Disable */ +#define DEBOUNCE_DIS3 0x2B /* Debounce Disable */ #define GPIO_PULL1 0x2C /* GPIO Pull Disable */ #define GPIO_PULL2 0x2D /* GPIO Pull Disable */ #define GPIO_PULL3 0x2E /* GPIO Pull Disable */ @@ -91,27 +92,27 @@ #define ADP5588_DEVICE_ID_MASK 0xF /* Configuration Register1 */ -#define ADP5588_AUTO_INC (1 << 7) -#define ADP5588_GPIEM_CFG (1 << 6) -#define ADP5588_OVR_FLOW_M (1 << 5) -#define ADP5588_INT_CFG (1 << 4) -#define ADP5588_OVR_FLOW_IEN (1 << 3) -#define ADP5588_K_LCK_IM (1 << 2) -#define ADP5588_GPI_IEN (1 << 1) -#define ADP5588_KE_IEN (1 << 0) +#define ADP5588_AUTO_INC BIT(7) +#define ADP5588_GPIEM_CFG BIT(6) +#define ADP5588_OVR_FLOW_M BIT(5) +#define ADP5588_INT_CFG BIT(4) +#define ADP5588_OVR_FLOW_IEN BIT(3) +#define ADP5588_K_LCK_IM BIT(2) +#define ADP5588_GPI_IEN BIT(1) +#define ADP5588_KE_IEN BIT(0) /* Interrupt Status Register */ -#define ADP5588_CMP2_INT (1 << 5) -#define ADP5588_CMP1_INT (1 << 4) -#define ADP5588_OVR_FLOW_INT (1 << 3) -#define ADP5588_K_LCK_INT (1 << 2) -#define ADP5588_GPI_INT (1 << 1) -#define ADP5588_KE_INT (1 << 0) +#define ADP5588_CMP2_INT BIT(5) +#define ADP5588_CMP1_INT BIT(4) +#define ADP5588_OVR_FLOW_INT BIT(3) +#define ADP5588_K_LCK_INT BIT(2) +#define ADP5588_GPI_INT BIT(1) +#define ADP5588_KE_INT BIT(0) /* Key Lock and Event Counter Register */ -#define ADP5588_K_LCK_EN (1 << 6) +#define ADP5588_K_LCK_EN BIT(6) #define ADP5588_LCK21 0x30 -#define ADP5588_KEC 0xF +#define ADP5588_KEC GENMASK(3, 0) #define ADP5588_MAXGPIO 18 #define ADP5588_BANK(offs) ((offs) >> 3) @@ -158,10 +159,10 @@ #define ADP5588_GPIMAPSIZE_MAX (GPI_PIN_END - GPI_PIN_BASE + 1) /* Key Event Register xy */ -#define KEY_EV_PRESSED (1 << 7) -#define KEY_EV_MASK (0x7F) +#define KEY_EV_PRESSED BIT(7) +#define KEY_EV_MASK GENMASK(6, 0) -#define KP_SEL(x) (0xFFFF >> (16 - x)) /* 2^x-1 */ +#define KP_SEL(x) (BIT(x) - 1) /* 2^x-1 */ #define KEYP_MAX_EVENT 10 @@ -211,7 +212,7 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) return i2c_smbus_write_byte_data(client, reg, val); } -static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) +static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned int off) { struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); @@ -231,7 +232,7 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) } static void adp5588_gpio_set_value(struct gpio_chip *chip, - unsigned off, int val) + unsigned int off, int val) { struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); @@ -244,8 +245,7 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, else kpad->dat_out[bank] &= ~bit; - adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, - kpad->dat_out[bank]); + adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, kpad->dat_out[bank]); mutex_unlock(&kpad->gpio_lock); } @@ -285,7 +285,7 @@ static int adp5588_gpio_set_config(struct gpio_chip *chip, unsigned int off, return ret; } -static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) +static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned int off) { struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); @@ -303,7 +303,7 @@ static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) } static int adp5588_gpio_direction_output(struct gpio_chip *chip, - unsigned off, int val) + unsigned int off, int val) { struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); @@ -320,12 +320,11 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, kpad->dat_out[bank] &= ~bit; ret = adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank, - kpad->dat_out[bank]); + kpad->dat_out[bank]); if (ret) goto out_unlock; - ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, - kpad->dir[bank]); + ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]); out_unlock: mutex_unlock(&kpad->gpio_lock); @@ -525,7 +524,7 @@ static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt) int i; for (i = 0; i < ev_cnt; i++) { - int key = adp5588_read(kpad->client, Key_EVENTA + i); + int key = adp5588_read(kpad->client, KEY_EVENTA + i); int key_val = key & KEY_EV_MASK; int key_press = key & KEY_EV_PRESSED; @@ -625,21 +624,20 @@ static int adp5588_setup(struct adp5588_kpad *kpad) } for (i = 0; i < KEYP_MAX_EVENT; i++) { - ret = adp5588_read(client, Key_EVENTA); + ret = adp5588_read(client, KEY_EVENTA); if (ret) return ret; } ret = adp5588_write(client, INT_STAT, - ADP5588_CMP2_INT | ADP5588_CMP1_INT | - ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | - ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */ + ADP5588_CMP2_INT | ADP5588_CMP1_INT | + ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | + ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */ if (ret) return ret; return adp5588_write(client, CFG, ADP5588_INT_CFG | - ADP5588_OVR_FLOW_IEN | - ADP5588_KE_IEN); + ADP5588_OVR_FLOW_IEN | ADP5588_KE_IEN); } static int adp5588_fw_parse(struct adp5588_kpad *kpad) @@ -723,7 +721,7 @@ static int adp5588_probe(struct i2c_client *client, int error; if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { + I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); return -EIO; } @@ -747,7 +745,7 @@ static int adp5588_probe(struct i2c_client *client, if (ret < 0) return ret; - revid = (u8) ret & ADP5588_DEVICE_ID_MASK; + revid = ret & ADP5588_DEVICE_ID_MASK; if (WA_DELAYED_READOUT_REVID(revid)) kpad->delay = msecs_to_jiffies(WA_DELAYED_READOUT_TIME); From cfacae58646462c5afedc8b42ad72a0968678e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 21:12:54 -0700 Subject: [PATCH 090/401] Input: adp5588-keys - add optional reset gpio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Optionally reset the device during probe. Signed-off-by: Nuno Sá Reviewed-by: Linus Walleij Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-9-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/adp5588-keys.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 565123e5894b..950abc1c25a3 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -716,6 +717,7 @@ static int adp5588_probe(struct i2c_client *client, { struct adp5588_kpad *kpad; struct input_dev *input; + struct gpio_desc *gpio; unsigned int revid; int ret; int error; @@ -741,6 +743,16 @@ static int adp5588_probe(struct i2c_client *client, if (error) return error; + gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + + if (gpio) { + fsleep(30); + gpiod_set_value_cansleep(gpio, 0); + fsleep(60); + } + ret = adp5588_read(client, DEV_ID); if (ret < 0) return ret; From 73d4a5423ecee8e108056134c53f82c7a95a90d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 21:13:10 -0700 Subject: [PATCH 091/401] Input: adp5588-keys - add regulator support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support feeding VCC through a regulator. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-10-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/adp5588-keys.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 950abc1c25a3..1db6b28db7ba 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -712,12 +713,18 @@ static int adp5588_fw_parse(struct adp5588_kpad *kpad) return 0; } +static void adp5588_disable_regulator(void *reg) +{ + regulator_disable(reg); +} + static int adp5588_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adp5588_kpad *kpad; struct input_dev *input; struct gpio_desc *gpio; + struct regulator *vcc; unsigned int revid; int ret; int error; @@ -743,6 +750,19 @@ static int adp5588_probe(struct i2c_client *client, if (error) return error; + vcc = devm_regulator_get(&client->dev, "vcc"); + if (IS_ERR(vcc)) + return PTR_ERR(vcc); + + error = regulator_enable(vcc); + if (error) + return error; + + error = devm_add_action_or_reset(&client->dev, + adp5588_disable_regulator, vcc); + if (error) + return error; + gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(gpio)) return PTR_ERR(gpio); From 4f35adaee07d182a4a7ef6b960c614ff3c5b4090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Tue, 30 Aug 2022 21:15:03 -0700 Subject: [PATCH 092/401] Input: adp5588-keys - use new PM macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the new PM macros (DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr()), the compiler has visibility to see that the functions are not used when !CONFIG_PM and hence, remove the dead code. As such, there's no need for '__maybe_unused'. Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220829131553.690063-11-nuno.sa@analog.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/adp5588-keys.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 1db6b28db7ba..7cd83c8e7110 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -827,7 +827,7 @@ static void adp5588_remove(struct i2c_client *client) /* all resources will be freed by devm */ } -static int __maybe_unused adp5588_suspend(struct device *dev) +static int adp5588_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -836,7 +836,7 @@ static int __maybe_unused adp5588_suspend(struct device *dev) return 0; } -static int __maybe_unused adp5588_resume(struct device *dev) +static int adp5588_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -845,7 +845,7 @@ static int __maybe_unused adp5588_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(adp5588_dev_pm_ops, adp5588_suspend, adp5588_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(adp5588_dev_pm_ops, adp5588_suspend, adp5588_resume); static const struct i2c_device_id adp5588_id[] = { { "adp5588-keys", 0 }, @@ -865,7 +865,7 @@ static struct i2c_driver adp5588_driver = { .driver = { .name = KBUILD_MODNAME, .of_match_table = adp5588_of_match, - .pm = &adp5588_dev_pm_ops, + .pm = pm_sleep_ptr(&adp5588_dev_pm_ops), }, .probe = adp5588_probe, .remove = adp5588_remove, From cf517fef601b9dde151f0afc27164d13bf1fd907 Mon Sep 17 00:00:00 2001 From: Billy Tsai Date: Thu, 18 Aug 2022 18:18:39 +0800 Subject: [PATCH 093/401] pinctrl: aspeed: Force to disable the function's signal When the driver want to disable the signal of the function, it doesn't need to query the state of the mux function's signal on a pin. The condition below will miss the disable of the signal: Ball | Default | P0 Signal | P0 Expression | Other -----+---------+-----------+-----------------------------+---------- E21 GPIOG0 SD2CLK SCU4B4[16]=1 & SCU450[1]=1 GPIOG0 -----+---------+-----------+-----------------------------+---------- B22 GPIOG1 SD2CMD SCU4B4[17]=1 & SCU450[1]=1 GPIOG1 -----+---------+-----------+-----------------------------+---------- Assume the register status like below: SCU4B4[16] == 1 & SCU4B4[17] == 1 & SCU450[1]==1 After the driver set the Ball E21 to the GPIOG0: SCU4B4[16] == 0 & SCU4B4[17] == 1 & SCU450[1]==0 When the driver want to set the Ball B22 to the GPIOG1, the condition of the SD2CMD will be false causing SCU4B4[17] not to be cleared. Signed-off-by: Billy Tsai Acked-by: Andrew Jeffery Link: https://lore.kernel.org/r/20220818101839.28860-1-billy_tsai@aspeedtech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c index 83d47ff1cea8..a30912a92f05 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c @@ -92,19 +92,10 @@ static int aspeed_sig_expr_enable(struct aspeed_pinmux_data *ctx, static int aspeed_sig_expr_disable(struct aspeed_pinmux_data *ctx, const struct aspeed_sig_expr *expr) { - int ret; - pr_debug("Disabling signal %s for %s\n", expr->signal, expr->function); - ret = aspeed_sig_expr_eval(ctx, expr, true); - if (ret < 0) - return ret; - - if (ret) - return aspeed_sig_expr_set(ctx, expr, false); - - return 0; + return aspeed_sig_expr_set(ctx, expr, false); } /** From 3160b37e5cb695e866e06c3fdbc385846b569294 Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Tue, 30 Aug 2022 16:35:25 +0530 Subject: [PATCH 094/401] pinctrl: amd: change dev_warn to dev_dbg for additional feature support Use dev_dbg instead of dev_warn for additional support of pinmux feature. Signed-off-by: Basavaraj Natikar Link: https://lore.kernel.org/r/20220830110525.1933198-1-Basavaraj.Natikar@amd.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index fda41907c4f1..ecf65237b263 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -1051,13 +1051,13 @@ static void amd_get_iomux_res(struct amd_gpio *gpio_dev) index = device_property_match_string(dev, "pinctrl-resource-names", "iomux"); if (index < 0) { - dev_warn(dev, "failed to get iomux index\n"); + dev_dbg(dev, "iomux not supported\n"); goto out_no_pinmux; } gpio_dev->iomux_base = devm_platform_ioremap_resource(gpio_dev->pdev, index); if (IS_ERR(gpio_dev->iomux_base)) { - dev_warn(dev, "Failed to get iomux %d io resource\n", index); + dev_dbg(dev, "iomux not supported %d io resource\n", index); goto out_no_pinmux; } From 87c2a29a6bf1a078d82427d42a2480a61814f8e3 Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Tue, 30 Aug 2022 16:27:27 +0200 Subject: [PATCH 095/401] pinctrl: imx8m: kconfig: Depends on SOC_IMX8M Change PINCTRL_IMX8M* dependency from just ARCH_MXC to SOC_IMX8M, likewise is done for other PINCTRL_IMX* kconfig. This avoid polluting the config when SOC_IMX8M is not enabled. Signed-off-by: Francesco Dolcini Reviewed-by: Fabio Estevam Link: https://lore.kernel.org/r/20220830142727.313080-1-francesco.dolcini@toradex.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index d96b1130efd3..365fcff8e470 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -119,28 +119,28 @@ config PINCTRL_IMX7ULP config PINCTRL_IMX8MM tristate "IMX8MM pinctrl driver" - depends on ARCH_MXC + depends on SOC_IMX8M select PINCTRL_IMX help Say Y here to enable the imx8mm pinctrl driver config PINCTRL_IMX8MN tristate "IMX8MN pinctrl driver" - depends on ARCH_MXC + depends on SOC_IMX8M select PINCTRL_IMX help Say Y here to enable the imx8mn pinctrl driver config PINCTRL_IMX8MP tristate "IMX8MP pinctrl driver" - depends on ARCH_MXC + depends on SOC_IMX8M select PINCTRL_IMX help Say Y here to enable the imx8mp pinctrl driver config PINCTRL_IMX8MQ tristate "IMX8MQ pinctrl driver" - depends on ARCH_MXC + depends on SOC_IMX8M select PINCTRL_IMX help Say Y here to enable the imx8mq pinctrl driver From 8a32cff217b7a0f1ab3b744fc9cd0626f08f7f15 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Wed, 31 Aug 2022 10:16:25 -0700 Subject: [PATCH 096/401] Input: colibri-vf50-ts - don't depend on VF610_ADC Any IIO ADC can be used with the driver, so do not depend on VF610_ADC. Signed-off-by: Max Krummenacher Signed-off-by: Francesco Dolcini Link: https://lore.kernel.org/r/20220712101619.326120-2-francesco.dolcini@toradex.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 2d70c945b20a..dc90a3ea51ee 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1335,7 +1335,7 @@ config TOUCHSCREEN_ZFORCE config TOUCHSCREEN_COLIBRI_VF50 tristate "Toradex Colibri on board touchscreen driver" - depends on IIO && VF610_ADC + depends on IIO depends on GPIOLIB || COMPILE_TEST help Say Y here if you have a Colibri VF50 and plan to use From a212f5ca5718d6f8c246d90e231aa76beb05bc23 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Wed, 31 Aug 2022 10:17:01 -0700 Subject: [PATCH 097/401] dt-bindings: input: colibri-vf50-ts: Improve documentation Clarify properties definition, drop unused pinctrl-2 state 'gpio'. Signed-off-by: Max Krummenacher Signed-off-by: Francesco Dolcini Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220712101619.326120-3-francesco.dolcini@toradex.com Signed-off-by: Dmitry Torokhov --- .../input/touchscreen/colibri-vf50-ts.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt index 2e1490a8fe74..ca304357c374 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt @@ -3,15 +3,16 @@ Required Properties: - compatible must be toradex,vf50-touchscreen - io-channels: adc channels being used by the Colibri VF50 module + IIO ADC for Y-, X-, Y+, X+ connections - xp-gpios: FET gate driver for input of X+ - xm-gpios: FET gate driver for input of X- - yp-gpios: FET gate driver for input of Y+ - ym-gpios: FET gate driver for input of Y- -- interrupts: pen irq interrupt for touch detection -- pinctrl-names: "idle", "default", "gpios" -- pinctrl-0: pinctrl node for pen/touch detection state pinmux +- interrupts: pen irq interrupt for touch detection, signal from X plate +- pinctrl-names: "idle", "default" +- pinctrl-0: pinctrl node for pen/touch detection, pinctrl must provide + pull-up resistor on X+, X-. - pinctrl-1: pinctrl node for X/Y and pressure measurement (ADC) state pinmux -- pinctrl-2: pinctrl node for gpios functioning as FET gate drivers - vf50-ts-min-pressure: pressure level at which to stop measuring X/Y values Example: @@ -26,9 +27,8 @@ Example: ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; interrupt-parent = <&gpio0>; interrupts = <8 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "idle","default","gpios"; - pinctrl-0 = <&pinctrl_touchctrl_idle>; - pinctrl-1 = <&pinctrl_touchctrl_default>; - pinctrl-2 = <&pinctrl_touchctrl_gpios>; + pinctrl-names = "idle","default"; + pinctrl-0 = <&pinctrl_touchctrl_idle>, <&pinctrl_touchctrl_gpios>; + pinctrl-1 = <&pinctrl_touchctrl_default>, <&pinctrl_touchctrl_gpios>; vf50-ts-min-pressure = <200>; }; From ed3d5bd20dcdfdbe110feeabf120cba7bd329ad8 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Fri, 12 Aug 2022 12:36:39 -0700 Subject: [PATCH 098/401] Input: rt5120 - add power key support Add RT5120 PMIC power key support. Signed-off-by: ChiYuan Huang Link: https://lore.kernel.org/r/1660100142-32493-4-git-send-email-u0084500@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 9 +++ drivers/input/misc/Makefile | 1 + drivers/input/misc/rt5120-pwrkey.c | 120 +++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 drivers/input/misc/rt5120-pwrkey.c diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 968240288c61..9f088900f863 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -909,6 +909,15 @@ config INPUT_SC27XX_VIBRA To compile this driver as a module, choose M here. The module will be called sc27xx_vibra. +config INPUT_RT5120_PWRKEY + tristate "RT5120 PMIC power key support" + depends on MFD_RT5120 || COMPILE_TEST + help + This enables support for RT5120 PMIC power key driver. + + To compile this driver as a module, choose M here. the module will + be called rt5120-pwrkey. + config INPUT_STPMIC1_ONKEY tristate "STPMIC1 PMIC Onkey support" depends on MFD_STPMIC1 diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 9eea13e98d48..6abefc41037b 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_INPUT_RAVE_SP_PWRBUTTON) += rave-sp-pwrbutton.o obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o obj-$(CONFIG_INPUT_REGULATOR_HAPTIC) += regulator-haptic.o obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o +obj-$(CONFIG_INPUT_RT5120_PWRKEY) += rt5120-pwrkey.o obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o obj-$(CONFIG_INPUT_RK805_PWRKEY) += rk805-pwrkey.o diff --git a/drivers/input/misc/rt5120-pwrkey.c b/drivers/input/misc/rt5120-pwrkey.c new file mode 100644 index 000000000000..8a8c1aeeed05 --- /dev/null +++ b/drivers/input/misc/rt5120-pwrkey.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 Richtek Technology Corp. + * Author: ChiYuan Huang + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RT5120_REG_INTSTAT 0x1E +#define RT5120_PWRKEYSTAT_MASK BIT(7) + +struct rt5120_priv { + struct regmap *regmap; + struct input_dev *input; +}; + +static irqreturn_t rt5120_pwrkey_handler(int irq, void *devid) +{ + struct rt5120_priv *priv = devid; + unsigned int stat; + int error; + + error = regmap_read(priv->regmap, RT5120_REG_INTSTAT, &stat); + if (error) + return IRQ_NONE; + + input_report_key(priv->input, KEY_POWER, + !(stat & RT5120_PWRKEYSTAT_MASK)); + input_sync(priv->input); + + return IRQ_HANDLED; +} + +static int rt5120_pwrkey_probe(struct platform_device *pdev) +{ + struct rt5120_priv *priv; + struct device *dev = &pdev->dev; + int press_irq, release_irq; + int error; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = dev_get_regmap(dev->parent, NULL); + if (!priv->regmap) { + dev_err(dev, "Failed to init regmap\n"); + return -ENODEV; + } + + press_irq = platform_get_irq_byname(pdev, "pwrkey-press"); + if (press_irq < 0) + return press_irq; + + release_irq = platform_get_irq_byname(pdev, "pwrkey-release"); + if (release_irq < 0) + return release_irq; + + /* Make input device be device resource managed */ + priv->input = devm_input_allocate_device(dev); + if (!priv->input) + return -ENOMEM; + + priv->input->name = "rt5120_pwrkey"; + priv->input->phys = "rt5120_pwrkey/input0"; + priv->input->id.bustype = BUS_I2C; + input_set_capability(priv->input, EV_KEY, KEY_POWER); + + error = input_register_device(priv->input); + if (error) { + dev_err(dev, "Failed to register input device: %d\n", error); + return error; + } + + error = devm_request_threaded_irq(dev, press_irq, + NULL, rt5120_pwrkey_handler, + 0, "pwrkey-press", priv); + if (error) { + dev_err(dev, + "Failed to register pwrkey press irq: %d\n", error); + return error; + } + + error = devm_request_threaded_irq(dev, release_irq, + NULL, rt5120_pwrkey_handler, + 0, "pwrkey-release", priv); + if (error) { + dev_err(dev, + "Failed to register pwrkey release irq: %d\n", error); + return error; + } + + return 0; +} + +static const struct of_device_id r5120_pwrkey_match_table[] = { + { .compatible = "richtek,rt5120-pwrkey" }, + {} +}; +MODULE_DEVICE_TABLE(of, r5120_pwrkey_match_table); + +static struct platform_driver rt5120_pwrkey_driver = { + .driver = { + .name = "rt5120-pwrkey", + .of_match_table = r5120_pwrkey_match_table, + }, + .probe = rt5120_pwrkey_probe, +}; +module_platform_driver(rt5120_pwrkey_driver); + +MODULE_AUTHOR("ChiYuan Huang "); +MODULE_DESCRIPTION("Richtek RT5120 power key driver"); +MODULE_LICENSE("GPL"); From f23b373f30fc9a8e77dec82d2a3d583c1eef155e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 30 Aug 2022 20:58:50 +0300 Subject: [PATCH 099/401] pinctrl: mcp23s08: Drop assignment of default number of OF cells The GPIO library code will assign default value for number of OF cells, no need to repeat this in the driver. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220830175850.44770-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-mcp23s08.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index 695236636d05..5f356edfd0fd 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -549,9 +549,6 @@ int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, mcp->chip.get = mcp23s08_get; mcp->chip.direction_output = mcp23s08_direction_output; mcp->chip.set = mcp23s08_set; -#ifdef CONFIG_OF_GPIO - mcp->chip.of_gpio_n_cells = 2; -#endif mcp->chip.base = base; mcp->chip.can_sleep = true; From 7fec8c9ceeedbe29be64c1b0a0610d40de39fcf8 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 31 Aug 2022 16:56:34 +0300 Subject: [PATCH 100/401] pinctrl: at91: use kernel-doc style for documentation of at91_gpio_chip Use kernel-doc style for documentation of struct at91_gpio_chip. Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220831135636.3176406-2-claudiu.beznea@microchip.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 5634fa063ebf..0b78fd48fd02 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -33,16 +33,28 @@ struct at91_pinctrl_mux_ops; +/** + * struct at91_gpio_chip: at91 gpio chip + * @chip: gpio chip + * @range: gpio range + * @next: bank sharing same clock + * @pioc_hwirq: PIO bank interrupt identifier on AIC + * @pioc_virq: PIO bank Linux virtual interrupt + * @pioc_idx: PIO bank index + * @regbase: PIO bank virtual address + * @clock: associated clock + * @ops: at91 pinctrl mux ops + */ struct at91_gpio_chip { struct gpio_chip chip; struct pinctrl_gpio_range range; - struct at91_gpio_chip *next; /* Bank sharing same clock */ - int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ - int pioc_virq; /* PIO bank Linux virtual interrupt */ - int pioc_idx; /* PIO bank index */ - void __iomem *regbase; /* PIO bank virtual address */ - struct clk *clock; /* associated clock */ - const struct at91_pinctrl_mux_ops *ops; /* ops */ + struct at91_gpio_chip *next; + int pioc_hwirq; + int pioc_virq; + int pioc_idx; + void __iomem *regbase; + struct clk *clock; + const struct at91_pinctrl_mux_ops *ops; }; static struct at91_gpio_chip *gpio_chips[MAX_GPIO_BANKS]; From a575207583676298f3999d41d86d81f7172fe950 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 31 Aug 2022 16:56:35 +0300 Subject: [PATCH 101/401] pinctrl: at91: move gpio suspend/resume calls to driver's context Move gpio suspend/resume execution local to driver and let it execute as close as possible to the moment the machine specific PM code is executed (by setting it to .noirq member of dev_pm_ops). With this the at91_pinctrl_gpio_suspend()/at91_pinctrl_gpio_resume() calls were removed from arch/arm/mach-at91/pm.c and also a header has been removed. The patch has been checked on sama5d3_xplained, sam9x60ek, sama5d2_xplained, sama7g5ek boards. Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220831135636.3176406-3-claudiu.beznea@microchip.com Signed-off-by: Linus Walleij --- arch/arm/mach-at91/pm.c | 15 ------- drivers/pinctrl/pinctrl-at91.c | 79 ++++++++++++++++------------------ include/soc/at91/pm.h | 16 ------- 3 files changed, 36 insertions(+), 74 deletions(-) delete mode 100644 include/soc/at91/pm.h diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index df6d673e83d5..a695710142db 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -19,8 +19,6 @@ #include #include -#include - #include #include #include @@ -624,16 +622,6 @@ static int at91_pm_enter(suspend_state_t state) if (ret) return ret; -#ifdef CONFIG_PINCTRL_AT91 - /* - * FIXME: this is needed to communicate between the pinctrl driver and - * the PM implementation in the machine. Possibly part of the PM - * implementation should be moved down into the pinctrl driver and get - * called as part of the generic suspend/resume path. - */ - at91_pinctrl_gpio_suspend(); -#endif - switch (state) { case PM_SUSPEND_MEM: case PM_SUSPEND_STANDBY: @@ -658,9 +646,6 @@ static int at91_pm_enter(suspend_state_t state) } error: -#ifdef CONFIG_PINCTRL_AT91 - at91_pinctrl_gpio_resume(); -#endif at91_pm_config_quirks(false); return 0; } diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 0b78fd48fd02..631a6289c2b6 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -22,8 +22,7 @@ #include /* Since we request GPIOs from ourself */ #include - -#include +#include #include "pinctrl-at91.h" #include "core.h" @@ -44,6 +43,9 @@ struct at91_pinctrl_mux_ops; * @regbase: PIO bank virtual address * @clock: associated clock * @ops: at91 pinctrl mux ops + * @wakeups: wakeup interrupts + * @backups: interrupts disabled in suspend + * @id: gpio chip identifier */ struct at91_gpio_chip { struct gpio_chip chip; @@ -55,6 +57,9 @@ struct at91_gpio_chip { void __iomem *regbase; struct clk *clock; const struct at91_pinctrl_mux_ops *ops; + u32 wakeups; + u32 backups; + u32 id; }; static struct at91_gpio_chip *gpio_chips[MAX_GPIO_BANKS]; @@ -1627,70 +1632,51 @@ static void gpio_irq_ack(struct irq_data *d) /* the interrupt is already cleared before by reading ISR */ } -static u32 wakeups[MAX_GPIO_BANKS]; -static u32 backups[MAX_GPIO_BANKS]; - static int gpio_irq_set_wake(struct irq_data *d, unsigned state) { struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); - unsigned bank = at91_gpio->pioc_idx; unsigned mask = 1 << d->hwirq; - if (unlikely(bank >= MAX_GPIO_BANKS)) - return -EINVAL; - if (state) - wakeups[bank] |= mask; + at91_gpio->wakeups |= mask; else - wakeups[bank] &= ~mask; + at91_gpio->wakeups &= ~mask; irq_set_irq_wake(at91_gpio->pioc_virq, state); return 0; } -void at91_pinctrl_gpio_suspend(void) +static int at91_gpio_suspend(struct device *dev) { - int i; + struct at91_gpio_chip *at91_chip = dev_get_drvdata(dev); + void __iomem *pio = at91_chip->regbase; - for (i = 0; i < gpio_banks; i++) { - void __iomem *pio; + at91_chip->backups = readl_relaxed(pio + PIO_IMR); + writel_relaxed(at91_chip->backups, pio + PIO_IDR); + writel_relaxed(at91_chip->wakeups, pio + PIO_IER); - if (!gpio_chips[i]) - continue; + if (!at91_chip->wakeups) + clk_disable_unprepare(at91_chip->clock); + else + printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", + 'A' + at91_chip->id, at91_chip->wakeups); - pio = gpio_chips[i]->regbase; - - backups[i] = readl_relaxed(pio + PIO_IMR); - writel_relaxed(backups[i], pio + PIO_IDR); - writel_relaxed(wakeups[i], pio + PIO_IER); - - if (!wakeups[i]) - clk_disable_unprepare(gpio_chips[i]->clock); - else - printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", - 'A'+i, wakeups[i]); - } + return 0; } -void at91_pinctrl_gpio_resume(void) +static int at91_gpio_resume(struct device *dev) { - int i; + struct at91_gpio_chip *at91_chip = dev_get_drvdata(dev); + void __iomem *pio = at91_chip->regbase; - for (i = 0; i < gpio_banks; i++) { - void __iomem *pio; + if (!at91_chip->wakeups) + clk_prepare_enable(at91_chip->clock); - if (!gpio_chips[i]) - continue; + writel_relaxed(at91_chip->wakeups, pio + PIO_IDR); + writel_relaxed(at91_chip->backups, pio + PIO_IER); - pio = gpio_chips[i]->regbase; - - if (!wakeups[i]) - clk_prepare_enable(gpio_chips[i]->clock); - - writel_relaxed(wakeups[i], pio + PIO_IDR); - writel_relaxed(backups[i], pio + PIO_IER); - } + return 0; } static void gpio_irq_handler(struct irq_desc *desc) @@ -1872,6 +1858,7 @@ static int at91_gpio_probe(struct platform_device *pdev) } at91_chip->chip = at91_gpio_template; + at91_chip->id = alias_idx; chip = &at91_chip->chip; chip->label = dev_name(&pdev->dev); @@ -1917,6 +1904,7 @@ static int at91_gpio_probe(struct platform_device *pdev) goto gpiochip_add_err; gpio_chips[alias_idx] = at91_chip; + platform_set_drvdata(pdev, at91_chip); gpio_banks = max(gpio_banks, alias_idx + 1); dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase); @@ -1932,10 +1920,15 @@ err: return ret; } +static const struct dev_pm_ops at91_gpio_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(at91_gpio_suspend, at91_gpio_resume) +}; + static struct platform_driver at91_gpio_driver = { .driver = { .name = "gpio-at91", .of_match_table = at91_gpio_of_match, + .pm = pm_ptr(&at91_gpio_pm_ops), }, .probe = at91_gpio_probe, }; diff --git a/include/soc/at91/pm.h b/include/soc/at91/pm.h deleted file mode 100644 index 7a41e53a3ffa..000000000000 --- a/include/soc/at91/pm.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Atmel Power Management - * - * Copyright (C) 2020 Atmel - * - * Author: Lee Jones - */ - -#ifndef __SOC_ATMEL_PM_H -#define __SOC_ATMEL_PM_H - -void at91_pinctrl_gpio_suspend(void); -void at91_pinctrl_gpio_resume(void); - -#endif /* __SOC_ATMEL_PM_H */ From 42eae17d56079591f945e409a4159e750ccc57df Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 31 Aug 2022 16:56:36 +0300 Subject: [PATCH 102/401] pinctrl: at91: use dev_dbg() instead of printk() Use dev_dbg() instead of printk(KERN_DEBUG) to avoid the following checkpatch.pl warning: "Prefer [subsystem eg: netdev]_dbg([subsystem]dev, ... then dev_dbg(dev, ... then pr_debug(... to printk(KERN_DEBUG ...". Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220831135636.3176406-4-claudiu.beznea@microchip.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 631a6289c2b6..81dbffab621f 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1659,8 +1659,8 @@ static int at91_gpio_suspend(struct device *dev) if (!at91_chip->wakeups) clk_disable_unprepare(at91_chip->clock); else - printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", - 'A' + at91_chip->id, at91_chip->wakeups); + dev_dbg(dev, "GPIO-%c may wake for %08x\n", + 'A' + at91_chip->id, at91_chip->wakeups); return 0; } From 1074e1d23a5c201b6558878a09f1d2b7c9506835 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 31 Aug 2022 16:55:12 +0300 Subject: [PATCH 103/401] pinctrl: pistachio: Switch to use fwnode instead of GPIO library now accepts fwnode as a firmware node, so switch the driver to use it. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220831135512.78407-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-pistachio.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl-pistachio.c b/drivers/pinctrl/pinctrl-pistachio.c index 5de691c630b4..940ed3fff63a 100644 --- a/drivers/pinctrl/pinctrl-pistachio.c +++ b/drivers/pinctrl/pinctrl-pistachio.c @@ -10,13 +10,13 @@ #include #include #include -#include -#include +#include #include #include #include #include #include +#include #include #include @@ -1347,46 +1347,45 @@ static struct pistachio_gpio_bank pistachio_gpio_banks[] = { static int pistachio_gpio_register(struct pistachio_pinctrl *pctl) { - struct device_node *node = pctl->dev->of_node; struct pistachio_gpio_bank *bank; unsigned int i; int irq, ret = 0; for (i = 0; i < pctl->nbanks; i++) { char child_name[sizeof("gpioXX")]; - struct device_node *child; + struct fwnode_handle *child; struct gpio_irq_chip *girq; snprintf(child_name, sizeof(child_name), "gpio%d", i); - child = of_get_child_by_name(node, child_name); + child = device_get_named_child_node(pctl->dev, child_name); if (!child) { dev_err(pctl->dev, "No node for bank %u\n", i); ret = -ENODEV; goto err; } - if (!of_find_property(child, "gpio-controller", NULL)) { + if (!fwnode_property_present(child, "gpio-controller")) { + fwnode_handle_put(child); dev_err(pctl->dev, "No gpio-controller property for bank %u\n", i); - of_node_put(child); ret = -ENODEV; goto err; } - irq = irq_of_parse_and_map(child, 0); - if (!irq) { + ret = fwnode_irq_get(child, 0); + if (ret < 0) { + fwnode_handle_put(child); dev_err(pctl->dev, "No IRQ for bank %u\n", i); - of_node_put(child); - ret = -EINVAL; goto err; } + irq = ret; bank = &pctl->gpio_banks[i]; bank->pctl = pctl; bank->base = pctl->base + GPIO_BANK_BASE(i); bank->gpio_chip.parent = pctl->dev; - bank->gpio_chip.of_node = child; + bank->gpio_chip.fwnode = child; girq = &bank->gpio_chip.irq; girq->chip = &bank->irq_chip; From c99e3ac632f9dfa4e363cf370dea7467ebb0f367 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 2 Sep 2022 22:11:17 -0700 Subject: [PATCH 104/401] Input: atkbd - switch to using dev_groups for driver-specific attributes The driver core now has the ability to handle the creation and removal of device-specific sysfs files, let's use it instead of registering and unregistering attributes by hand. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20220903051119.1332808-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index d4131236d18c..246958795f60 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -323,11 +323,13 @@ static umode_t atkbd_attr_is_visible(struct kobject *kobj, return attr->mode; } -static struct attribute_group atkbd_attribute_group = { +static const struct attribute_group atkbd_attribute_group = { .attrs = atkbd_attributes, .is_visible = atkbd_attr_is_visible, }; +__ATTRIBUTE_GROUPS(atkbd_attribute); + static const unsigned int xl_table[] = { ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, @@ -922,8 +924,6 @@ static void atkbd_disconnect(struct serio *serio) { struct atkbd *atkbd = serio_get_drvdata(serio); - sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); - atkbd_disable(atkbd); input_unregister_device(atkbd->dev); @@ -1271,21 +1271,16 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - err = sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group); - if (err) - goto fail3; - atkbd_enable(atkbd); if (serio->write) atkbd_activate(atkbd); err = input_register_device(atkbd->dev); if (err) - goto fail4; + goto fail3; return 0; - fail4: sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); fail3: serio_close(serio); fail2: serio_set_drvdata(serio, NULL); fail1: input_free_device(dev); @@ -1378,7 +1373,8 @@ MODULE_DEVICE_TABLE(serio, atkbd_serio_ids); static struct serio_driver atkbd_drv = { .driver = { - .name = "atkbd", + .name = "atkbd", + .dev_groups = atkbd_attribute_groups, }, .description = DRIVER_DESC, .id_table = atkbd_serio_ids, From fd30a4ba81f94e7297a3fb3c0d83879a4e4b2591 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 2 Sep 2022 22:11:18 -0700 Subject: [PATCH 105/401] Input: psmouse - switch to using dev_groups for driver-specific attributes The driver core now has the ability to handle the creation and removal of device-specific sysfs files, let's use it instead of registering and unregistering attributes by hand. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20220903051119.1332808-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 0b4a3039f312..c9a7e87b273e 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -94,7 +94,7 @@ PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO, (void *) offsetof(struct psmouse, resync_time), psmouse_show_int_attr, psmouse_set_int_attr); -static struct attribute *psmouse_attributes[] = { +static struct attribute *psmouse_dev_attrs[] = { &psmouse_attr_protocol.dattr.attr, &psmouse_attr_rate.dattr.attr, &psmouse_attr_resolution.dattr.attr, @@ -103,9 +103,7 @@ static struct attribute *psmouse_attributes[] = { NULL }; -static const struct attribute_group psmouse_attribute_group = { - .attrs = psmouse_attributes, -}; +ATTRIBUTE_GROUPS(psmouse_dev); /* * psmouse_mutex protects all operations changing state of mouse @@ -1481,8 +1479,6 @@ static void psmouse_disconnect(struct serio *serio) struct psmouse *psmouse = serio_get_drvdata(serio); struct psmouse *parent = NULL; - sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group); - mutex_lock(&psmouse_mutex); psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); @@ -1647,10 +1643,6 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) if (parent && parent->pt_activate) parent->pt_activate(parent); - error = sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group); - if (error) - goto err_pt_deactivate; - /* * PS/2 devices having SMBus companions should stay disabled * on PS/2 side, in order to have SMBus part operable. @@ -1666,13 +1658,6 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) mutex_unlock(&psmouse_mutex); return retval; - err_pt_deactivate: - if (parent && parent->pt_deactivate) - parent->pt_deactivate(parent); - if (input_dev) { - input_unregister_device(input_dev); - input_dev = NULL; /* so we don't try to free it below */ - } err_protocol_disconnect: if (psmouse->disconnect) psmouse->disconnect(psmouse); @@ -1791,7 +1776,8 @@ MODULE_DEVICE_TABLE(serio, psmouse_serio_ids); static struct serio_driver psmouse_drv = { .driver = { - .name = "psmouse", + .name = "psmouse", + .dev_groups = psmouse_dev_groups, }, .description = DRIVER_DESC, .id_table = psmouse_serio_ids, From f4e7a254299bcdfe7bced700a7d96690b1b9a6f2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 2 Sep 2022 22:11:19 -0700 Subject: [PATCH 106/401] Input: aiptek - switch to using dev_groups for driver-specific attributes The driver core now has the ability to handle the creation and removal of device-specific sysfs files, let's use it instead of registering and unregistering attributes by hand. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20220903051119.1332808-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/aiptek.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 24ec4844a5c3..baabc51547b8 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1617,7 +1617,7 @@ static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *at static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL); -static struct attribute *aiptek_attributes[] = { +static struct attribute *aiptek_dev_attrs[] = { &dev_attr_size.attr, &dev_attr_pointer_mode.attr, &dev_attr_coordinate_mode.attr, @@ -1641,9 +1641,7 @@ static struct attribute *aiptek_attributes[] = { NULL }; -static const struct attribute_group aiptek_attribute_group = { - .attrs = aiptek_attributes, -}; +ATTRIBUTE_GROUPS(aiptek_dev); /*********************************************************************** * This routine is called when a tablet has been identified. It basically @@ -1842,26 +1840,16 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) */ usb_set_intfdata(intf, aiptek); - /* Set up the sysfs files - */ - err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group); - if (err) { - dev_warn(&intf->dev, "cannot create sysfs group err: %d\n", - err); - goto fail3; - } - /* Register the tablet as an Input Device */ err = input_register_device(aiptek->inputdev); if (err) { dev_warn(&intf->dev, "input_register_device returned err: %d\n", err); - goto fail4; + goto fail3; } return 0; - fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); fail3: usb_free_urb(aiptek->urb); fail2: usb_free_coherent(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, aiptek->data_dma); @@ -1886,7 +1874,6 @@ static void aiptek_disconnect(struct usb_interface *intf) */ usb_kill_urb(aiptek->urb); input_unregister_device(aiptek->inputdev); - sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group); usb_free_urb(aiptek->urb); usb_free_coherent(interface_to_usbdev(intf), AIPTEK_PACKET_LENGTH, @@ -1900,6 +1887,7 @@ static struct usb_driver aiptek_driver = { .probe = aiptek_probe, .disconnect = aiptek_disconnect, .id_table = aiptek_ids, + .dev_groups = aiptek_dev_groups, }; module_usb_driver(aiptek_driver); From ba5829c6543fbcf0b31854cc6970b9012ff71279 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Sun, 4 Sep 2022 11:43:14 -0500 Subject: [PATCH 107/401] ipmi:ipmb: Fix a vague comment and a typo Sending an IPMI response message gets a reponse to the response, but the comment saying that just said "response response", which is hard to understand. Also fix an obvious typo. Reported-by: Shaomin Deng Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_ipmb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ipmb.c b/drivers/char/ipmi/ipmi_ipmb.c index ab19b4b3317e..1019946abe4e 100644 --- a/drivers/char/ipmi/ipmi_ipmb.c +++ b/drivers/char/ipmi/ipmi_ipmb.c @@ -218,8 +218,8 @@ static void ipmi_ipmb_send_response(struct ipmi_ipmb_dev *iidev, { if ((msg->data[0] >> 2) & 1) { /* - * It's a response being sent, we needto return a - * response response. Fake a send msg command + * It's a response being sent, we need to return a + * response to the response. Fake a send msg command * response with channel 0. This will always be ipmb * direct. */ From 4a13796aeb84c94e1883d4f93904a94284f8e5ea Mon Sep 17 00:00:00 2001 From: Jiangshan Yi Date: Mon, 5 Sep 2022 15:13:00 +0800 Subject: [PATCH 108/401] pinctrl: berlin: fix spelling typo in comment Fix spelling typo in comment. Reported-by: k2ci Signed-off-by: Jiangshan Yi Link: https://lore.kernel.org/r/20220905071300.1832105-1-13667453960@163.com Signed-off-by: Linus Walleij --- drivers/pinctrl/berlin/berlin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c index a073eedd71aa..1e427ea4d31b 100644 --- a/drivers/pinctrl/berlin/berlin.c +++ b/drivers/pinctrl/berlin/berlin.c @@ -209,7 +209,7 @@ static int berlin_pinctrl_build_state(struct platform_device *pdev) for (i = 0; i < pctrl->desc->ngroups; i++) { desc_group = pctrl->desc->groups + i; - /* compute the maxiumum number of functions a group can have */ + /* compute the maximum number of functions a group can have */ max_functions += 1 << (desc_group->bit_width + 1); } From 94b22e125175e0c57d044c18d122ad5991348ca3 Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Mon, 5 Sep 2022 20:15:17 -0700 Subject: [PATCH 109/401] dt-bindings: input: touchscreen: stmpe: Remove node name requirement STMPE driver does not require a specific node name anymore, only the compatible is checked, update binding according to this. Signed-off-by: Francesco Dolcini Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220712163345.445811-6-francesco.dolcini@toradex.com Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/input/touchscreen/stmpe.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt index c549924603d2..238b51555c04 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt @@ -54,8 +54,7 @@ Optional properties common with MFD (deprecated): 1 -> 3.25 MHz 2 || 3 -> 6.5 MHz -Node name must be stmpe_touchscreen and should be child node of stmpe node to -which it belongs. +Node should be child node of stmpe node to which it belongs. Note that common ADC settings of stmpe_touchscreen (child) will take precedence over the settings done in MFD. From b382c5e37344883dc97525d05f1f6b788f549985 Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Thu, 18 Aug 2022 17:44:08 +0200 Subject: [PATCH 110/401] Input: xpad - add supported devices as contributed on github This is based on multiple commits at https://github.com/paroj/xpad Cc: stable@vger.kernel.org Signed-off-by: Jasper Poppe Signed-off-by: Jeremy Palmer Signed-off-by: Ruineka Signed-off-by: Cleber de Mattos Casali Signed-off-by: Kyle Gospodnetich Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20220818154411.510308-2-rojtberg@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 18190b529bca..5af07ded98fc 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -113,6 +113,8 @@ static const struct xpad_device { u8 xtype; } xpad_device[] = { { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 }, + { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 }, + { 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 }, { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, @@ -244,6 +246,7 @@ static const struct xpad_device { { 0x0f0d, 0x0063, "Hori Real Arcade Pro Hayabusa (USA) Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, { 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE }, { 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, + { 0x0f0d, 0x00c5, "Hori Fighting Commander ONE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, { 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX }, { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, @@ -260,6 +263,7 @@ static const struct xpad_device { { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 }, { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, + { 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 }, { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, @@ -325,6 +329,7 @@ static const struct xpad_device { { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 }, + { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 }, { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE }, @@ -334,6 +339,14 @@ static const struct xpad_device { { 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 }, { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 }, { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, + { 0x2563, 0x058d, "OneXPlayer Gamepad", 0, XTYPE_XBOX360 }, + { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, + { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 }, { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 }, { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, @@ -419,6 +432,7 @@ static const signed short xpad_abs_triggers[] = { static const struct usb_device_id xpad_table[] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 Controller */ + XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */ XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ @@ -429,6 +443,7 @@ static const struct usb_device_id xpad_table[] = { { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */ XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz GamePad */ + XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */ XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ @@ -450,8 +465,12 @@ static const struct usb_device_id xpad_table[] = { XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA Controllers */ XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */ XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */ + XPAD_XBOX360_VENDOR(0x2563), /* OneXPlayer Gamepad */ + XPAD_XBOX360_VENDOR(0x260d), /* Dareu H101 */ + XPAD_XBOXONE_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller for Xbox */ XPAD_XBOXONE_VENDOR(0x2e24), /* Hyperkin Duke X-Box One pad */ XPAD_XBOX360_VENDOR(0x2f24), /* GameSir Controllers */ + XPAD_XBOX360_VENDOR(0x31e3), /* Wooting Keyboards */ XPAD_XBOX360_VENDOR(0x3285), /* Nacon GC-100 */ { } }; From a17b9841152e7f4621619902b347e2cc39c32996 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 18 Aug 2022 17:44:09 +0200 Subject: [PATCH 111/401] Input: xpad - fix wireless 360 controller breaking after suspend Suspending and resuming the system can sometimes cause the out URB to get hung after a reset_resume. This causes LED setting and force feedback to break on resume. To avoid this, just drop the reset_resume callback so the USB core rebinds xpad to the wireless pads on resume if a reset happened. A nice side effect of this change is the LED ring on wireless controllers is now set correctly on system resume. Cc: stable@vger.kernel.org Fixes: 4220f7db1e42 ("Input: xpad - workaround dead irq_out after suspend/ resume") Signed-off-by: Cameron Gutman Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20220818154411.510308-3-rojtberg@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 5af07ded98fc..3da5fd5b5aaf 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -1991,7 +1991,6 @@ static struct usb_driver xpad_driver = { .disconnect = xpad_disconnect, .suspend = xpad_suspend, .resume = xpad_resume, - .reset_resume = xpad_resume, .id_table = xpad_table, }; From da7e2128b869a1315b8919ded42b799076279cda Mon Sep 17 00:00:00 2001 From: Santosh De Massari Date: Thu, 18 Aug 2022 17:44:10 +0200 Subject: [PATCH 112/401] Input: xpad - Poweroff XBOX360W on mode button long press Newer gamepads turn themselves off when the mode button is held down. For XBOX360W gamepads we must do this in the driver. Do not use BIT() macro for consistency within the file. Signed-off-by: Santosh De Massari Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20220818154411.510308-4-rojtberg@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 3da5fd5b5aaf..d770221709c0 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -89,6 +89,11 @@ #define XTYPE_XBOXONE 3 #define XTYPE_UNKNOWN 4 +/* Send power-off packet to xpad360w after holding the mode button for this many + * seconds + */ +#define XPAD360W_POWEROFF_TIMEOUT 5 + static bool dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); @@ -630,11 +635,13 @@ struct usb_xpad { int pad_nr; /* the order x360 pads were attached */ const char *name; /* name of the device */ struct work_struct work; /* init/remove device from callback */ + time64_t mode_btn_down_ts; }; static int xpad_init_input(struct usb_xpad *xpad); static void xpad_deinit_input(struct usb_xpad *xpad); static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num); +static void xpad360w_poweroff_controller(struct usb_xpad *xpad); /* * xpad_process_packet @@ -786,6 +793,23 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, } input_sync(dev); + + /* XBOX360W controllers can't be turned off without driver assistance */ + if (xpad->xtype == XTYPE_XBOX360W) { + if (xpad->mode_btn_down_ts > 0 && xpad->pad_present && + ((ktime_get_seconds() - xpad->mode_btn_down_ts) >= + XPAD360W_POWEROFF_TIMEOUT)) { + xpad360w_poweroff_controller(xpad); + xpad->mode_btn_down_ts = 0; + return; + } + + /* mode button down/up */ + if (data[3] & 0x04) + xpad->mode_btn_down_ts = ktime_get_seconds(); + else + xpad->mode_btn_down_ts = 0; + } } static void xpad_presence_work(struct work_struct *work) From e23c69e3324892f7420686b3aaa0403df6cf152c Mon Sep 17 00:00:00 2001 From: Christopher Crockett Date: Thu, 18 Aug 2022 17:44:11 +0200 Subject: [PATCH 113/401] Input: xpad - add support for XBOX One Elite paddles An effort has been made to support every official model and firmware version I could track down info on. The following controllers _should_ have working paddles with this PR: - Xbox Elite (**untested**) - Xbox Elite Series 2 on early firmwares (**untested**) - Xbox Elite Series 2 on v4 firmwares (Tested v4.8.1908.0) - Xbox Elite Series 2 on v5 pre-BLE firmwares (**untested**) - Xbox Elite Series 2 on v5 post-BLE firmwares (Tested v5.13.3143.0) This patch also introduces correct handling for the Elite 1 controller and properly suppresses paddle inputs when using a custom profile slot. Starting with firmware v5.11, certain inputs for the Elite 2 were moved to an extra packet that is not enabled by default. We must first manually enable this extra packet in order to correctly process paddle input data with these later firmwares. Signed-off-by: Christopher Crockett Signed-off-by: Pavel Rojtberg Tested-by: Bastien Nocera Link: https://lore.kernel.org/r/20220818154411.510308-5-rojtberg@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 270 +++++++++++++++++++++++++--------- 1 file changed, 201 insertions(+), 69 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index d770221709c0..fceb0d342945 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -80,6 +80,7 @@ #define MAP_TRIGGERS_TO_BUTTONS (1 << 1) #define MAP_STICKS_TO_NULL (1 << 2) #define MAP_SELECT_BUTTON (1 << 3) +#define MAP_PADDLES (1 << 4) #define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) @@ -94,6 +95,12 @@ */ #define XPAD360W_POWEROFF_TIMEOUT 5 +#define PKT_XB 0 +#define PKT_XBE1 1 +#define PKT_XBE2_FW_OLD 2 +#define PKT_XBE2_FW_5_EARLY 3 +#define PKT_XBE2_FW_5_11 4 + static bool dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); @@ -116,6 +123,7 @@ static const struct xpad_device { char *name; u8 mapping; u8 xtype; + u8 packet_type; } xpad_device[] = { { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 }, { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 }, @@ -135,7 +143,8 @@ static const struct xpad_device { { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE }, - { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE }, + { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE }, + { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE }, { 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE }, { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE }, @@ -408,6 +417,13 @@ static const signed short xpad_abs_triggers[] = { -1 }; +/* used when the controller has extra paddle buttons */ +static const signed short xpad_btn_paddles[] = { + BTN_TRIGGER_HAPPY5, BTN_TRIGGER_HAPPY6, /* paddle upper right, lower right */ + BTN_TRIGGER_HAPPY7, BTN_TRIGGER_HAPPY8, /* paddle upper left, lower left */ + -1 /* terminating entry */ +}; + /* * Xbox 360 has a vendor-specific class, so we cannot match it with only * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we @@ -516,6 +532,15 @@ static const u8 xboxone_s_init[] = { 0x05, 0x20, 0x00, 0x0f, 0x06 }; +/* + * This packet is required to get additional input data + * from Xbox One Elite Series 2 (0x045e:0x0b00) pads. + * We mostly do this right now to get paddle data + */ +static const u8 extra_input_packet_init[] = { + 0x4d, 0x10, 0x01, 0x02, 0x07, 0x00 +}; + /* * This packet is required for the Titanfall 2 Xbox One pads * (0x0e6f:0x0165) to finish initialization and for Hori pads @@ -576,6 +601,7 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init), XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init), + XBOXONE_INIT_PKT(0x045e, 0x0b00, extra_input_packet_init), XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1), XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2), XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), @@ -632,6 +658,7 @@ struct usb_xpad { int mapping; /* map d-pad to buttons or to axes */ int xtype; /* type of xbox device */ + int packet_type; /* type of the extended packet */ int pad_nr; /* the order x360 pads were attached */ const char *name; /* name of the device */ struct work_struct work; /* init/remove device from callback */ @@ -889,6 +916,7 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) { struct input_dev *dev = xpad->dev; + bool do_sync = false; /* the xbox button has its own special report */ if (data[0] == 0X07) { @@ -901,75 +929,140 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char xpadone_ack_mode_report(xpad, data[2]); input_report_key(dev, BTN_MODE, data[4] & 0x01); + + do_sync = true; + } else if (data[0] == 0X0C) { + /* Some packet formats force us to use this separate to poll paddle inputs */ + if (xpad->packet_type == PKT_XBE2_FW_5_11) { + /* Mute paddles if controller is in a custom profile slot + * Checked by looking at the active profile slot to + * verify it's the default slot + */ + if (data[19] != 0) + data[18] = 0; + + /* Elite Series 2 split packet paddle bits */ + input_report_key(dev, BTN_TRIGGER_HAPPY5, data[18] & 0x01); + input_report_key(dev, BTN_TRIGGER_HAPPY6, data[18] & 0x02); + input_report_key(dev, BTN_TRIGGER_HAPPY7, data[18] & 0x04); + input_report_key(dev, BTN_TRIGGER_HAPPY8, data[18] & 0x08); + + do_sync = true; + } + } else if (data[0] == 0X20) { /* The main valid packet type for inputs */ + /* menu/view buttons */ + input_report_key(dev, BTN_START, data[4] & 0x04); + input_report_key(dev, BTN_SELECT, data[4] & 0x08); + if (xpad->mapping & MAP_SELECT_BUTTON) + input_report_key(dev, KEY_RECORD, data[22] & 0x01); + + /* buttons A,B,X,Y */ + input_report_key(dev, BTN_A, data[4] & 0x10); + input_report_key(dev, BTN_B, data[4] & 0x20); + input_report_key(dev, BTN_X, data[4] & 0x40); + input_report_key(dev, BTN_Y, data[4] & 0x80); + + /* digital pad */ + if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { + /* dpad as buttons (left, right, up, down) */ + input_report_key(dev, BTN_TRIGGER_HAPPY1, data[5] & 0x04); + input_report_key(dev, BTN_TRIGGER_HAPPY2, data[5] & 0x08); + input_report_key(dev, BTN_TRIGGER_HAPPY3, data[5] & 0x01); + input_report_key(dev, BTN_TRIGGER_HAPPY4, data[5] & 0x02); + } else { + input_report_abs(dev, ABS_HAT0X, + !!(data[5] & 0x08) - !!(data[5] & 0x04)); + input_report_abs(dev, ABS_HAT0Y, + !!(data[5] & 0x02) - !!(data[5] & 0x01)); + } + + /* TL/TR */ + input_report_key(dev, BTN_TL, data[5] & 0x10); + input_report_key(dev, BTN_TR, data[5] & 0x20); + + /* stick press left/right */ + input_report_key(dev, BTN_THUMBL, data[5] & 0x40); + input_report_key(dev, BTN_THUMBR, data[5] & 0x80); + + if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { + /* left stick */ + input_report_abs(dev, ABS_X, + (__s16) le16_to_cpup((__le16 *)(data + 10))); + input_report_abs(dev, ABS_Y, + ~(__s16) le16_to_cpup((__le16 *)(data + 12))); + + /* right stick */ + input_report_abs(dev, ABS_RX, + (__s16) le16_to_cpup((__le16 *)(data + 14))); + input_report_abs(dev, ABS_RY, + ~(__s16) le16_to_cpup((__le16 *)(data + 16))); + } + + /* triggers left/right */ + if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { + input_report_key(dev, BTN_TL2, + (__u16) le16_to_cpup((__le16 *)(data + 6))); + input_report_key(dev, BTN_TR2, + (__u16) le16_to_cpup((__le16 *)(data + 8))); + } else { + input_report_abs(dev, ABS_Z, + (__u16) le16_to_cpup((__le16 *)(data + 6))); + input_report_abs(dev, ABS_RZ, + (__u16) le16_to_cpup((__le16 *)(data + 8))); + } + + /* paddle handling */ + /* based on SDL's SDL_hidapi_xboxone.c */ + if (xpad->mapping & MAP_PADDLES) { + if (xpad->packet_type == PKT_XBE1) { + /* Mute paddles if controller has a custom mapping applied. + * Checked by comparing the current mapping + * config against the factory mapping config + */ + if (memcmp(&data[4], &data[18], 2) != 0) + data[32] = 0; + + /* OG Elite Series Controller paddle bits */ + input_report_key(dev, BTN_TRIGGER_HAPPY5, data[32] & 0x02); + input_report_key(dev, BTN_TRIGGER_HAPPY6, data[32] & 0x08); + input_report_key(dev, BTN_TRIGGER_HAPPY7, data[32] & 0x01); + input_report_key(dev, BTN_TRIGGER_HAPPY8, data[32] & 0x04); + } else if (xpad->packet_type == PKT_XBE2_FW_OLD) { + /* Mute paddles if controller has a custom mapping applied. + * Checked by comparing the current mapping + * config against the factory mapping config + */ + if (data[19] != 0) + data[18] = 0; + + /* Elite Series 2 4.x firmware paddle bits */ + input_report_key(dev, BTN_TRIGGER_HAPPY5, data[18] & 0x01); + input_report_key(dev, BTN_TRIGGER_HAPPY6, data[18] & 0x02); + input_report_key(dev, BTN_TRIGGER_HAPPY7, data[18] & 0x04); + input_report_key(dev, BTN_TRIGGER_HAPPY8, data[18] & 0x08); + } else if (xpad->packet_type == PKT_XBE2_FW_5_EARLY) { + /* Mute paddles if controller has a custom mapping applied. + * Checked by comparing the current mapping + * config against the factory mapping config + */ + if (data[23] != 0) + data[22] = 0; + + /* Elite Series 2 5.x firmware paddle bits + * (before the packet was split) + */ + input_report_key(dev, BTN_TRIGGER_HAPPY5, data[22] & 0x01); + input_report_key(dev, BTN_TRIGGER_HAPPY6, data[22] & 0x02); + input_report_key(dev, BTN_TRIGGER_HAPPY7, data[22] & 0x04); + input_report_key(dev, BTN_TRIGGER_HAPPY8, data[22] & 0x08); + } + } + + do_sync = true; + } + + if (do_sync) input_sync(dev); - return; - } - /* check invalid packet */ - else if (data[0] != 0X20) - return; - - /* menu/view buttons */ - input_report_key(dev, BTN_START, data[4] & 0x04); - input_report_key(dev, BTN_SELECT, data[4] & 0x08); - if (xpad->mapping & MAP_SELECT_BUTTON) - input_report_key(dev, KEY_RECORD, data[22] & 0x01); - - /* buttons A,B,X,Y */ - input_report_key(dev, BTN_A, data[4] & 0x10); - input_report_key(dev, BTN_B, data[4] & 0x20); - input_report_key(dev, BTN_X, data[4] & 0x40); - input_report_key(dev, BTN_Y, data[4] & 0x80); - - /* digital pad */ - if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { - /* dpad as buttons (left, right, up, down) */ - input_report_key(dev, BTN_TRIGGER_HAPPY1, data[5] & 0x04); - input_report_key(dev, BTN_TRIGGER_HAPPY2, data[5] & 0x08); - input_report_key(dev, BTN_TRIGGER_HAPPY3, data[5] & 0x01); - input_report_key(dev, BTN_TRIGGER_HAPPY4, data[5] & 0x02); - } else { - input_report_abs(dev, ABS_HAT0X, - !!(data[5] & 0x08) - !!(data[5] & 0x04)); - input_report_abs(dev, ABS_HAT0Y, - !!(data[5] & 0x02) - !!(data[5] & 0x01)); - } - - /* TL/TR */ - input_report_key(dev, BTN_TL, data[5] & 0x10); - input_report_key(dev, BTN_TR, data[5] & 0x20); - - /* stick press left/right */ - input_report_key(dev, BTN_THUMBL, data[5] & 0x40); - input_report_key(dev, BTN_THUMBR, data[5] & 0x80); - - if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { - /* left stick */ - input_report_abs(dev, ABS_X, - (__s16) le16_to_cpup((__le16 *)(data + 10))); - input_report_abs(dev, ABS_Y, - ~(__s16) le16_to_cpup((__le16 *)(data + 12))); - - /* right stick */ - input_report_abs(dev, ABS_RX, - (__s16) le16_to_cpup((__le16 *)(data + 14))); - input_report_abs(dev, ABS_RY, - ~(__s16) le16_to_cpup((__le16 *)(data + 16))); - } - - /* triggers left/right */ - if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { - input_report_key(dev, BTN_TL2, - (__u16) le16_to_cpup((__le16 *)(data + 6))); - input_report_key(dev, BTN_TR2, - (__u16) le16_to_cpup((__le16 *)(data + 8))); - } else { - input_report_abs(dev, ABS_Z, - (__u16) le16_to_cpup((__le16 *)(data + 6))); - input_report_abs(dev, ABS_RZ, - (__u16) le16_to_cpup((__le16 *)(data + 8))); - } - - input_sync(dev); } static void xpad_irq_in(struct urb *urb) @@ -1736,6 +1829,12 @@ static int xpad_init_input(struct usb_xpad *xpad) xpad_btn_pad[i]); } + /* set up paddles if the controller has them */ + if (xpad->mapping & MAP_PADDLES) { + for (i = 0; xpad_btn_paddles[i] >= 0; i++) + input_set_capability(input_dev, EV_KEY, xpad_btn_paddles[i]); + } + /* * This should be a simple else block. However historically * xbox360w has mapped DPAD to buttons while xbox360 did not. This @@ -1822,6 +1921,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->mapping = xpad_device[i].mapping; xpad->xtype = xpad_device[i].xtype; xpad->name = xpad_device[i].name; + xpad->packet_type = PKT_XB; INIT_WORK(&xpad->work, xpad_presence_work); if (xpad->xtype == XTYPE_UNKNOWN) { @@ -1887,6 +1987,38 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id usb_set_intfdata(intf, xpad); + /* Packet type detection */ + if (le16_to_cpu(udev->descriptor.idVendor) == 0x045e) { /* Microsoft controllers */ + if (le16_to_cpu(udev->descriptor.idProduct) == 0x02e3) { + /* The original elite controller always uses the oldest + * type of extended packet + */ + xpad->packet_type = PKT_XBE1; + } else if (le16_to_cpu(udev->descriptor.idProduct) == 0x0b00) { + /* The elite 2 controller has seen multiple packet + * revisions. These are tied to specific firmware + * versions + */ + if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x0500) { + /* This is the format that the Elite 2 used + * prior to the BLE update + */ + xpad->packet_type = PKT_XBE2_FW_OLD; + } else if (le16_to_cpu(udev->descriptor.bcdDevice) < + 0x050b) { + /* This is the format that the Elite 2 used + * prior to the update that split the packet + */ + xpad->packet_type = PKT_XBE2_FW_5_EARLY; + } else { + /* The split packet format that was introduced + * in firmware v5.11 + */ + xpad->packet_type = PKT_XBE2_FW_5_11; + } + } + } + if (xpad->xtype == XTYPE_XBOX360W) { /* * Submit the int URB immediately rather than waiting for open From f5d620254c978746020a5be09f7b2a84dd9daa48 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:34 +0300 Subject: [PATCH 114/401] pinctrl: cy8c95x0: make irq_chip immutable Since recently, the kernel is nagging about mutable irq_chips: "not an immutable chip, please consider fixing it!" Drop the unneeded copy, flag it as IRQCHIP_IMMUTABLE, add the new helper functions and call the appropriate gpiolib functions. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 32 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 05791212822e..efc6ba1089fb 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -90,7 +90,6 @@ MODULE_DEVICE_TABLE(of, cy8c95x0_dt_ids); * @irq_trig_high: I/O bits affected by a high voltage level * @push_pull: I/O bits configured as push pull driver * @shiftmask: Mask used to compensate for Gport2 width - * @irq_chip: IRQ chip configuration * @nport: Number of Gports in this chip * @gpio_chip: gpiolib chip * @driver_data: private driver data @@ -112,7 +111,6 @@ struct cy8c95x0_pinctrl { DECLARE_BITMAP(irq_trig_high, MAX_LINE); DECLARE_BITMAP(push_pull, MAX_LINE); DECLARE_BITMAP(shiftmask, MAX_LINE); - struct irq_chip irq_chip; int nport; struct gpio_chip gpio_chip; unsigned long driver_data; @@ -844,16 +842,20 @@ static void cy8c95x0_irq_mask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); - set_bit(irqd_to_hwirq(d), chip->irq_mask); + set_bit(hwirq, chip->irq_mask); + gpiochip_disable_irq(gc, hwirq); } static void cy8c95x0_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); - clear_bit(irqd_to_hwirq(d), chip->irq_mask); + gpiochip_enable_irq(gc, hwirq); + clear_bit(hwirq, chip->irq_mask); } static void cy8c95x0_irq_bus_lock(struct irq_data *d) @@ -931,6 +933,18 @@ static void cy8c95x0_irq_shutdown(struct irq_data *d) clear_bit(hwirq, chip->irq_trig_high); } +static const struct irq_chip cy8c95x0_irqchip = { + .name = "cy8c95x0-irq", + .irq_mask = cy8c95x0_irq_mask, + .irq_unmask = cy8c95x0_irq_unmask, + .irq_bus_lock = cy8c95x0_irq_bus_lock, + .irq_bus_sync_unlock = cy8c95x0_irq_bus_sync_unlock, + .irq_set_type = cy8c95x0_irq_set_type, + .irq_shutdown = cy8c95x0_irq_shutdown, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static bool cy8c95x0_irq_pending(struct cy8c95x0_pinctrl *chip, unsigned long *pending) { DECLARE_BITMAP(ones, MAX_LINE); @@ -1136,7 +1150,6 @@ static const struct pinconf_ops cy8c95x0_pinconf_ops = { static int cy8c95x0_irq_setup(struct cy8c95x0_pinctrl *chip, int irq) { - struct irq_chip *irq_chip = &chip->irq_chip; struct gpio_irq_chip *girq = &chip->gpio_chip.irq; DECLARE_BITMAP(pending_irqs, MAX_LINE); int ret; @@ -1155,15 +1168,8 @@ static int cy8c95x0_irq_setup(struct cy8c95x0_pinctrl *chip, int irq) /* Mask all interrupts */ bitmap_fill(chip->irq_mask, MAX_LINE); - irq_chip->name = devm_kasprintf(chip->dev, GFP_KERNEL, "%s-irq", chip->name); - irq_chip->irq_mask = cy8c95x0_irq_mask; - irq_chip->irq_unmask = cy8c95x0_irq_unmask; - irq_chip->irq_bus_lock = cy8c95x0_irq_bus_lock; - irq_chip->irq_bus_sync_unlock = cy8c95x0_irq_bus_sync_unlock; - irq_chip->irq_set_type = cy8c95x0_irq_set_type; - irq_chip->irq_shutdown = cy8c95x0_irq_shutdown; + gpio_irq_chip_set_chip(girq, &cy8c95x0_irqchip); - girq->chip = irq_chip; /* This will let us handle the parent IRQ in the driver */ girq->parent_handler = NULL; girq->num_parents = 0; From ad3d55aab4c08cdfc127753c5c5db78218cff4b2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:35 +0300 Subject: [PATCH 115/401] pinctrl: cy8c95x0: Allow IRQ chip core to handle numbering No need to assign first line number for IRQ chip. Let IRQ core to decide. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-2-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index efc6ba1089fb..529664894e20 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1177,7 +1177,6 @@ static int cy8c95x0_irq_setup(struct cy8c95x0_pinctrl *chip, int irq) girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_simple_irq; girq->threaded = true; - girq->first = 0; ret = devm_request_threaded_irq(chip->dev, irq, NULL, cy8c95x0_irq_handler, From 43dcf873d48d363d73fda0834c63d02ad177827e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:37 +0300 Subject: [PATCH 116/401] pinctrl: cy8c95x0: Fix return value in cy8c95x0_detect() It's an obvious typo in never tested piece of code that successful detection shouldn't fail. Fix that. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-4-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 529664894e20..2e46446c05ff 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1266,7 +1266,7 @@ static int cy8c95x0_detect(struct i2c_client *client, dev_info(&client->dev, "Found a %s chip at 0x%02x.\n", name, client->addr); strscpy(info->type, name, I2C_NAME_SIZE); - return -ENODEV; + return 0; } static int cy8c95x0_probe(struct i2c_client *client) From 641d6cc65dd4b783dd73ecfbface5e7a961c2f11 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:38 +0300 Subject: [PATCH 117/401] pinctrl: cy8c95x0: Fix pin control name to enable more than one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Cypress GPIO expander is an I²C discrete component. Hence the platform may contain more than one of a such. Currently this has limitations in the driver due to same name used for all chips of a type. Replace this with device instance specific name. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-5-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 2e46446c05ff..fa3764e768a4 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1199,8 +1199,7 @@ static int cy8c95x0_setup_pinctrl(struct cy8c95x0_pinctrl *chip) pd->confops = &cy8c95x0_pinconf_ops; pd->pmxops = &cy8c95x0_pmxops; pd->npins = chip->gpio_chip.ngpio; - pd->name = devm_kasprintf(chip->dev, GFP_KERNEL, "pinctrl-%s", - chip->name); + pd->name = dev_name(chip->dev); pd->pins = cy8c9560_pins; pd->npins = chip->tpin; pd->owner = THIS_MODULE; From 28ce127238f4bd3aaf5b6666f48f8e2a34b81579 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:39 +0300 Subject: [PATCH 118/401] pinctrl: cy8c95x0: Drop unneeded npins assignment The npins field is assigned twice. Remove the first occurrence. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-6-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index fa3764e768a4..a511044ea60a 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1198,7 +1198,6 @@ static int cy8c95x0_setup_pinctrl(struct cy8c95x0_pinctrl *chip) pd->pctlops = &cy8c95x0_pinctrl_ops; pd->confops = &cy8c95x0_pinconf_ops; pd->pmxops = &cy8c95x0_pmxops; - pd->npins = chip->gpio_chip.ngpio; pd->name = dev_name(chip->dev); pd->pins = cy8c9560_pins; pd->npins = chip->tpin; From d86e0344852eb65688c31227ee5a1e081f49e1bd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:40 +0300 Subject: [PATCH 119/401] pinctrl: cy8c95x0: Enable GPIO range Since it's a pin control, GPIO counterpart needs to know the mapping between pin numbering and GPIO numbering. Enable this by calling gpiochip_add_pin_range() at the chip addition time. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-7-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index a511044ea60a..2e05585c88db 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -812,7 +812,20 @@ static void cy8c95x0_gpio_set_multiple(struct gpio_chip *gc, cy8c95x0_write_regs_mask(chip, CY8C95X0_OUTPUT, bits, mask); } -static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip, int ngpio) +static int cy8c95x0_add_pin_ranges(struct gpio_chip *gc) +{ + struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); + struct device *dev = chip->dev; + int ret; + + ret = gpiochip_add_pin_range(gc, dev_name(dev), 0, 0, chip->tpin); + if (ret) + dev_err(dev, "failed to add GPIO pin range\n"); + + return ret; +} + +static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip) { struct gpio_chip *gc = &chip->gpio_chip; @@ -825,9 +838,10 @@ static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip, int ngpio) gc->set_multiple = cy8c95x0_gpio_set_multiple; gc->set_config = cy8c95x0_gpio_set_config; gc->can_sleep = true; + gc->add_pin_ranges = cy8c95x0_add_pin_ranges; gc->base = -1; - gc->ngpio = ngpio; + gc->ngpio = chip->tpin; gc->parent = chip->dev; gc->owner = THIS_MODULE; @@ -1339,11 +1353,11 @@ static int cy8c95x0_probe(struct i2c_client *client) goto err_exit; } - ret = cy8c95x0_setup_gpiochip(chip, chip->tpin); + ret = cy8c95x0_setup_pinctrl(chip); if (ret) goto err_exit; - ret = cy8c95x0_setup_pinctrl(chip); + ret = cy8c95x0_setup_gpiochip(chip); if (ret) goto err_exit; From 44c2533366d2259ce861d5e3adfb0237a844ffa4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:41 +0300 Subject: [PATCH 120/401] pinctrl: cy8c95x0: Remove device initialization The Cypress CY8C95x0 chips have an internal EEPROM that defines initial configuration. It might be that bootloader or other entity wrote the platform related setup into it. Don't override it in the driver. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-8-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 2e05585c88db..804dce0840f7 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1224,30 +1224,6 @@ static int cy8c95x0_setup_pinctrl(struct cy8c95x0_pinctrl *chip) return 0; } -static int device_cy8c95x0_init(struct cy8c95x0_pinctrl *chip) -{ - DECLARE_BITMAP(ones, MAX_LINE); - DECLARE_BITMAP(zeros, MAX_LINE); - int ret; - - /* Set all pins to input. This is the POR default. */ - bitmap_fill(ones, MAX_LINE); - ret = cy8c95x0_write_regs_mask(chip, CY8C95X0_DIRECTION, ones, ones); - if (ret) { - dev_err(chip->dev, "Failed to set pins to input\n"); - return ret; - } - - bitmap_zero(zeros, MAX_LINE); - ret = cy8c95x0_write_regs_mask(chip, CY8C95X0_INVERT, zeros, ones); - if (ret) { - dev_err(chip->dev, "Failed to set polarity inversion\n"); - return ret; - } - - return 0; -} - static int cy8c95x0_detect(struct i2c_client *client, struct i2c_board_info *info) { @@ -1343,10 +1319,6 @@ static int cy8c95x0_probe(struct i2c_client *client) bitmap_set(chip->shiftmask, 0, 20); mutex_init(&chip->i2c_lock); - ret = device_cy8c95x0_init(chip); - if (ret) - goto err_exit; - if (client->irq) { ret = cy8c95x0_irq_setup(chip, client->irq); if (ret) From a416bfb7d595b423cf50af58f1ea9263f233fbd5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:42 +0300 Subject: [PATCH 121/401] pinctrl: cy8c95x0: Remove useless conditionals The pin control framework checks pin boundaries before calling the respective driver's callbacks. Hence no need to check for pin boundaries, the respective conditionals won't be ever true. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-9-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 804dce0840f7..fef735bea648 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1040,14 +1040,6 @@ static int cy8c95x0_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, const unsigned int **pins, unsigned int *num_pins) { - struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); - - if (group >= chip->tpin) { - *pins = NULL; - *num_pins = 0; - return 0; - } - *pins = &cy8c9560_pins[group].number; *num_pins = 1; return 0; @@ -1115,9 +1107,6 @@ static int cy8c95x0_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, { struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); - if (group >= chip->tpin) - return -EINVAL; - return cy8c95x0_pinmux_cfg(chip, selector, group); } @@ -1144,9 +1133,6 @@ static int cy8c95x0_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, int ret = 0; int i; - if (WARN_ON(pin >= chip->tpin)) - return -EINVAL; - for (i = 0; i < num_configs; i++) { ret = cy8c95x0_gpio_set_pincfg(chip, pin, configs[i]); if (ret) From 1fa3df901f2c80d6a597abe462725e5a374b2795 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:43 +0300 Subject: [PATCH 122/401] pinctrl: cy8c95x0: Remove custom ->set_config() Since we have pin configuration getter and setter provided, there is no need to duplicate that in the custom ->set_config(). Instead, switch to gpiochip_generic_config(). Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-10-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index fef735bea648..204a53d6c4c9 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -772,30 +772,6 @@ out: return ret; } -static int cy8c95x0_gpio_set_config(struct gpio_chip *gc, unsigned int offset, - unsigned long config) -{ - struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc); - unsigned long arg = pinconf_to_config_argument(config); - - switch (pinconf_to_config_param(config)) { - case PIN_CONFIG_INPUT_ENABLE: - return cy8c95x0_gpio_direction_input(gc, offset); - case PIN_CONFIG_OUTPUT: - return cy8c95x0_gpio_direction_output(gc, offset, arg); - case PIN_CONFIG_MODE_PWM: - case PIN_CONFIG_BIAS_PULL_UP: - case PIN_CONFIG_BIAS_PULL_DOWN: - case PIN_CONFIG_BIAS_DISABLE: - case PIN_CONFIG_DRIVE_OPEN_DRAIN: - case PIN_CONFIG_DRIVE_OPEN_SOURCE: - case PIN_CONFIG_DRIVE_PUSH_PULL: - return cy8c95x0_gpio_set_pincfg(chip, offset, config); - default: - return -ENOTSUPP; - } -} - static int cy8c95x0_gpio_get_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { @@ -836,7 +812,7 @@ static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip) gc->get_direction = cy8c95x0_gpio_get_direction; gc->get_multiple = cy8c95x0_gpio_get_multiple; gc->set_multiple = cy8c95x0_gpio_set_multiple; - gc->set_config = cy8c95x0_gpio_set_config; + gc->set_config = gpiochip_generic_config, gc->can_sleep = true; gc->add_pin_ranges = cy8c95x0_add_pin_ranges; From c3e4095287afbc8954928ae79849766194d364ac Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:44 +0300 Subject: [PATCH 123/401] pinctrl: cy8c95x0: Use 'default' in all switch-cases Move the default values to the 'default' case in the switches. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-11-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 204a53d6c4c9..c714c438f641 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -279,9 +279,9 @@ static bool cy8c95x0_readable_register(struct device *dev, unsigned int reg) switch (reg) { case 0x24 ... 0x27: return false; + default: + return true; } - - return true; } static bool cy8c95x0_writeable_register(struct device *dev, unsigned int reg) @@ -293,9 +293,9 @@ static bool cy8c95x0_writeable_register(struct device *dev, unsigned int reg) return false; case 0x24 ... 0x27: return false; + default: + return true; } - - return true; } static bool cy8c95x0_volatile_register(struct device *dev, unsigned int reg) @@ -325,9 +325,9 @@ static bool cy8c95x0_precious_register(struct device *dev, unsigned int reg) switch (reg) { case CY8C95X0_INTSTATUS_(0) ... CY8C95X0_INTSTATUS_(7): return true; + default: + return false; } - - return false; } static const struct reg_default cy8c95x0_reg_defaults[] = { @@ -1255,6 +1255,8 @@ static int cy8c95x0_probe(struct i2c_client *client) case 60: strscpy(chip->name, cy8c95x0_id[2].name, I2C_NAME_SIZE); break; + default: + return -ENODEV; } reg = devm_regulator_get(&client->dev, "vdd"); From f12352f334c28a85e738f9caa31a0c5b07febd20 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:45 +0300 Subject: [PATCH 124/401] pinctrl: cy8c95x0: Implement ->pin_dbg_show() The introduced callback ->pin_dbg_show() is useful for debugging. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-12-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 42 +++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index c714c438f641..e1900db54c16 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1021,27 +1021,51 @@ static int cy8c95x0_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, return 0; } +static const char *cy8c95x0_get_fname(unsigned int selector) +{ + if (selector == 0) + return "gpio"; + else + return "pwm"; +} + +static void cy8c95x0_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int pin) +{ + struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); + DECLARE_BITMAP(mask, MAX_LINE); + DECLARE_BITMAP(pwm, MAX_LINE); + + bitmap_zero(mask, MAX_LINE); + __set_bit(pin, mask); + + if (cy8c95x0_read_regs_mask(chip, CY8C95X0_PWMSEL, pwm, mask)) { + seq_puts(s, "not available"); + return; + } + + seq_printf(s, "MODE:%s", cy8c95x0_get_fname(test_bit(pin, pwm))); +} + static const struct pinctrl_ops cy8c95x0_pinctrl_ops = { .get_groups_count = cy8c95x0_pinctrl_get_groups_count, .get_group_name = cy8c95x0_pinctrl_get_group_name, .get_group_pins = cy8c95x0_pinctrl_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, .dt_free_map = pinconf_generic_dt_free_map, + .pin_dbg_show = cy8c95x0_pin_dbg_show, }; +static const char *cy8c95x0_get_functions_name(struct pinctrl_dev *pctldev, unsigned int selector) +{ + return cy8c95x0_get_fname(selector); +} + static int cy8c95x0_get_functions_count(struct pinctrl_dev *pctldev) { return 2; } -static const char *cy8c95x0_get_fname(struct pinctrl_dev *pctldev, unsigned int selector) -{ - if (selector == 0) - return "gpio"; - else - return "pwm"; -} - static int cy8c95x0_get_groups(struct pinctrl_dev *pctldev, unsigned int selector, const char * const **groups, unsigned int * const num_groups) @@ -1088,7 +1112,7 @@ static int cy8c95x0_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, static const struct pinmux_ops cy8c95x0_pmxops = { .get_functions_count = cy8c95x0_get_functions_count, - .get_function_name = cy8c95x0_get_fname, + .get_function_name = cy8c95x0_get_functions_name, .get_function_groups = cy8c95x0_get_groups, .set_mux = cy8c95x0_set_mux, .strict = true, From 8586466e4f11a5879a7c0df5d25da6c6a7d7c672 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:46 +0300 Subject: [PATCH 125/401] pinctrl: cy8c95x0: Make use of device properties Convert the module to be property provider agnostic and allow it to be used on non-OF platforms. Add mod_devicetable.h include. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-13-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 2 +- drivers/pinctrl/pinctrl-cy8c95x0.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index fc0e529e633f..c09562fbb1b7 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -137,7 +137,7 @@ config PINCTRL_BM1880 config PINCTRL_CY8C95X0 tristate "Cypress CY8C95X0 I2C pinctrl and GPIO driver" - depends on I2C && OF + depends on I2C select GPIOLIB select GPIOLIB_IRQCHIP select PINMUX diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index e1900db54c16..e0f99c82f621 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -13,15 +13,16 @@ #include #include #include +#include #include -#include -#include +#include +#include +#include + #include #include #include #include -#include -#include /* Fast access registers */ #define CY8C95X0_INPUT 0x00 @@ -1051,8 +1052,10 @@ static const struct pinctrl_ops cy8c95x0_pinctrl_ops = { .get_groups_count = cy8c95x0_pinctrl_get_groups_count, .get_group_name = cy8c95x0_pinctrl_get_group_name, .get_group_pins = cy8c95x0_pinctrl_get_group_pins, +#ifdef CONFIG_OF .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, .dt_free_map = pinconf_generic_dt_free_map, +#endif .pin_dbg_show = cy8c95x0_pin_dbg_show, }; @@ -1256,9 +1259,8 @@ static int cy8c95x0_probe(struct i2c_client *client) chip->dev = &client->dev; /* Set the device type */ - if (client->dev.of_node) - chip->driver_data = (unsigned long)of_device_get_match_data(&client->dev); - else + chip->driver_data = (unsigned long)device_get_match_data(&client->dev); + if (!chip->driver_data) chip->driver_data = i2c_match_id(cy8c95x0_id, client)->driver_data; if (!chip->driver_data) From 618a43ff1f37603164ac82cfa0734a39c079a3e9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:47 +0300 Subject: [PATCH 126/401] pinctrl: cy8c95x0: support ACPI device found on Galileo Gen1 Add support of the expander found on Intel Galileo Gen1 board. The platform information comes from ACPI. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-14-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index e0f99c82f621..18a9f5a8ab2d 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1339,10 +1339,17 @@ static void cy8c95x0_remove(struct i2c_client *client) regulator_disable(chip->regulator); } +static const struct acpi_device_id cy8c95x0_acpi_ids[] = { + { "INT3490", 40, }, + { } +}; +MODULE_DEVICE_TABLE(acpi, cy8c95x0_acpi_ids); + static struct i2c_driver cy8c95x0_driver = { .driver = { .name = "cy8c95x0-pinctrl", .of_match_table = cy8c95x0_dt_ids, + .acpi_match_table = cy8c95x0_acpi_ids, }, .probe_new = cy8c95x0_probe, .remove = cy8c95x0_remove, From 785b1bd8546eb0d9e70bd4d859583c33aaceeb9b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:48 +0300 Subject: [PATCH 127/401] pinctrl: cy8c95x0: Override IRQ for one of the expanders on Galileo Gen 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ACPI table on Intel Galileo Gen 1 has wrong pin number for IRQ resource of the I²C GPIO expander. Since we know what that number is and luckily have GPIO bases fixed for SoC's controllers, we may use a simple DMI quirk to match the platform and retrieve GpioInt() pin on it for the expander in question. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-15-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 18a9f5a8ab2d..a42790950182 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -7,7 +7,9 @@ * Author: Naresh Solanki */ +#include #include +#include #include #include #include @@ -73,6 +75,46 @@ static const struct of_device_id cy8c95x0_dt_ids[] = { MODULE_DEVICE_TABLE(of, cy8c95x0_dt_ids); +static const struct acpi_gpio_params cy8c95x0_irq_gpios = { 0, 0, true }; + +static const struct acpi_gpio_mapping cy8c95x0_acpi_irq_gpios[] = { + { "irq-gpios", &cy8c95x0_irq_gpios, 1, ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER }, + { } +}; + +static int cy8c95x0_acpi_get_irq(struct device *dev) +{ + int ret; + + ret = devm_acpi_dev_add_driver_gpios(dev, cy8c95x0_acpi_irq_gpios); + if (ret) + dev_warn(dev, "can't add GPIO ACPI mapping\n"); + + ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0); + if (ret < 0) + return ret; + + dev_info(dev, "ACPI interrupt quirk (IRQ %d)\n", ret); + return ret; +} + +static const struct dmi_system_id cy8c95x0_dmi_acpi_irq_info[] = { + { + /* + * On Intel Galileo Gen 1 board the IRQ pin is provided + * as an absolute number instead of being relative. + * Since first controller (gpio-sch.c) and second + * (gpio-dwapb.c) are at the fixed bases, we may safely + * refer to the number in the global space to get an IRQ + * out of it. + */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"), + }, + }, + {} +}; + #define MAX_BANK 8 #define BANK_SZ 8 #define MAX_LINE (MAX_BANK * BANK_SZ) @@ -1309,6 +1351,12 @@ static int cy8c95x0_probe(struct i2c_client *client) bitmap_set(chip->shiftmask, 0, 20); mutex_init(&chip->i2c_lock); + if (dmi_first_match(cy8c95x0_dmi_acpi_irq_info)) { + ret = cy8c95x0_acpi_get_irq(&client->dev); + if (ret > 0) + client->irq = ret; + } + if (client->irq) { ret = cy8c95x0_irq_setup(chip, client->irq); if (ret) From 9540a8360673350526615e1dfe4993ba06de0f15 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:49 +0300 Subject: [PATCH 128/401] pinctrl: cy8c95x0: use bits.h macros for all masks Make use of the GENMASK() (far less error-prone, far more concise). Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-16-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index a42790950182..c8f86c3f526f 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -374,14 +374,14 @@ static bool cy8c95x0_precious_register(struct device *dev, unsigned int reg) } static const struct reg_default cy8c95x0_reg_defaults[] = { - { CY8C95X0_OUTPUT_(0), 0xff }, - { CY8C95X0_OUTPUT_(1), 0xff }, - { CY8C95X0_OUTPUT_(2), 0xff }, - { CY8C95X0_OUTPUT_(3), 0xff }, - { CY8C95X0_OUTPUT_(4), 0xff }, - { CY8C95X0_OUTPUT_(5), 0xff }, - { CY8C95X0_OUTPUT_(6), 0xff }, - { CY8C95X0_OUTPUT_(7), 0xff }, + { CY8C95X0_OUTPUT_(0), GENMASK(7, 0) }, + { CY8C95X0_OUTPUT_(1), GENMASK(7, 0) }, + { CY8C95X0_OUTPUT_(2), GENMASK(7, 0) }, + { CY8C95X0_OUTPUT_(3), GENMASK(7, 0) }, + { CY8C95X0_OUTPUT_(4), GENMASK(7, 0) }, + { CY8C95X0_OUTPUT_(5), GENMASK(7, 0) }, + { CY8C95X0_OUTPUT_(6), GENMASK(7, 0) }, + { CY8C95X0_OUTPUT_(7), GENMASK(7, 0) }, { CY8C95X0_PORTSEL, 0 }, { CY8C95X0_PWMSEL, 0 }, }; @@ -1268,7 +1268,7 @@ static int cy8c95x0_detect(struct i2c_client *client, ret = i2c_smbus_read_byte_data(client, CY8C95X0_DEVID); if (ret < 0) return ret; - switch (ret & 0xf0) { + switch (ret & GENMASK(7, 4)) { case 0x20: name = cy8c95x0_id[0].name; break; From 63e23304488f25f7193d5868b6cef02cf3a05e66 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 2 Sep 2022 21:26:50 +0300 Subject: [PATCH 129/401] pinctrl: cy8c95x0: Correct comment style In a few comments the style is not aligned with the rest. Correct them. While at it, drop unneeded blank lines and deduplicate 'Author'. Signed-off-by: Andy Shevchenko Tested-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220902182650.83098-17-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index c8f86c3f526f..1335d07822f9 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -3,8 +3,8 @@ * CY8C95X0 20/40/60 pin I2C GPIO port expander with interrupt support * * Copyright (C) 2022 9elements GmbH - * Author: Patrick Rudolph - * Author: Naresh Solanki + * Authors: Patrick Rudolph + * Naresh Solanki */ #include @@ -37,7 +37,7 @@ /* Port Select configures the port */ #define CY8C95X0_PORTSEL 0x18 -/* port settings, write PORTSEL first */ +/* Port settings, write PORTSEL first */ #define CY8C95X0_INTMASK 0x19 #define CY8C95X0_PWMSEL 0x1A #define CY8C95X0_INVERT 0x1B @@ -72,7 +72,6 @@ static const struct of_device_id cy8c95x0_dt_ids[] = { { .compatible = "cypress,cy8c9560", .data = OF_CY8C95X(60), }, { } }; - MODULE_DEVICE_TABLE(of, cy8c95x0_dt_ids); static const struct acpi_gpio_params cy8c95x0_irq_gpios = { 0, 0, true }; @@ -429,7 +428,7 @@ static int cy8c95x0_write_regs_mask(struct cy8c95x0_pinctrl *chip, int reg, continue; switch (reg) { - /* muxed registers */ + /* Muxed registers */ case CY8C95X0_INTMASK: case CY8C95X0_PWMSEL: case CY8C95X0_INVERT: @@ -446,7 +445,7 @@ static int cy8c95x0_write_regs_mask(struct cy8c95x0_pinctrl *chip, int reg, goto out; off = reg; break; - /* direct access registers */ + /* Direct access registers */ case CY8C95X0_INPUT: case CY8C95X0_OUTPUT: case CY8C95X0_INTSTATUS: @@ -500,7 +499,7 @@ static int cy8c95x0_read_regs_mask(struct cy8c95x0_pinctrl *chip, int reg, continue; switch (reg) { - /* muxed registers */ + /* Muxed registers */ case CY8C95X0_INTMASK: case CY8C95X0_PWMSEL: case CY8C95X0_INVERT: @@ -517,7 +516,7 @@ static int cy8c95x0_read_regs_mask(struct cy8c95x0_pinctrl *chip, int reg, goto out; off = reg; break; - /* direct access registers */ + /* Direct access registers */ case CY8C95X0_INPUT: case CY8C95X0_OUTPUT: case CY8C95X0_INTSTATUS: @@ -592,18 +591,18 @@ static int cy8c95x0_gpio_direction_output(struct gpio_chip *gc, u8 bit = cypress_get_pin_mask(chip, off); int ret; - /* set output level */ + /* Set output level */ ret = regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0); if (ret) return ret; mutex_lock(&chip->i2c_lock); - /* select port */ + /* Select port... */ ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); if (ret) goto out; - /* then direction */ + /* ...then direction */ ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, 0); out: @@ -624,7 +623,7 @@ static int cy8c95x0_gpio_get_value(struct gpio_chip *gc, unsigned int off) if (ret < 0) { /* * NOTE: - * diagnostic already emitted; that's all we should + * Diagnostic already emitted; that's all we should * do unless gpio_*_value_cansleep() calls become different * from their nonsleeping siblings (and report faults). */ @@ -687,7 +686,7 @@ static int cy8c95x0_gpio_get_pincfg(struct cy8c95x0_pinctrl *chip, mutex_lock(&chip->i2c_lock); - /* select port */ + /* Select port */ ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); if (ret < 0) goto out; @@ -742,7 +741,8 @@ static int cy8c95x0_gpio_get_pincfg(struct cy8c95x0_pinctrl *chip, ret = -ENOTSUPP; goto out; } - /* Writing 1 to one of the drive mode registers will automatically + /* + * Writing 1 to one of the drive mode registers will automatically * clear conflicting set bits in the other drive mode registers. */ ret = regmap_read(chip->regmap, reg, ®_val); @@ -768,7 +768,7 @@ static int cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl *chip, mutex_lock(&chip->i2c_lock); - /* select port */ + /* Select port */ ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); if (ret < 0) goto out; @@ -805,7 +805,8 @@ static int cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl *chip, ret = -ENOTSUPP; goto out; } - /* Writing 1 to one of the drive mode registers will automatically + /* + * Writing 1 to one of the drive mode registers will automatically * clear conflicting set bits in the other drive mode registers. */ ret = regmap_write_bits(chip->regmap, reg, bit, bit); @@ -1130,7 +1131,7 @@ static int cy8c95x0_pinmux_cfg(struct cy8c95x0_pinctrl *chip, u8 bit = cypress_get_pin_mask(chip, off); int ret; - /* select port */ + /* Select port */ ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port); if (ret < 0) return ret; @@ -1247,11 +1248,12 @@ static int cy8c95x0_setup_pinctrl(struct cy8c95x0_pinctrl *chip) pd->pins = cy8c9560_pins; pd->npins = chip->tpin; pd->owner = THIS_MODULE; - chip->pctldev = devm_pinctrl_register(chip->dev, pd, chip); + chip->pctldev = devm_pinctrl_register(chip->dev, pd, chip); if (IS_ERR(chip->pctldev)) return dev_err_probe(chip->dev, PTR_ERR(chip->pctldev), "can't register controller\n"); + return 0; } @@ -1304,7 +1306,6 @@ static int cy8c95x0_probe(struct i2c_client *client) chip->driver_data = (unsigned long)device_get_match_data(&client->dev); if (!chip->driver_data) chip->driver_data = i2c_match_id(cy8c95x0_id, client)->driver_data; - if (!chip->driver_data) return -ENODEV; @@ -1404,7 +1405,6 @@ static struct i2c_driver cy8c95x0_driver = { .id_table = cy8c95x0_id, .detect = cy8c95x0_detect, }; - module_i2c_driver(cy8c95x0_driver); MODULE_AUTHOR("Patrick Rudolph "); From 71e268e3426d2a1a4fcf3d88079d1d977fd034e0 Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Tue, 6 Sep 2022 00:44:08 +0200 Subject: [PATCH 130/401] pinctrl: imx8m: kconfig: Fix build error on test compile PINCTRL_IMX depends on OF, however the dependency is missed when selected by PINCTRL_IMX8M* (it does not follow the indirect 'select' statements), select it explicitly. Cc: Arnd Bergmann Cc: Linus Walleij Reported-by: kernel test robot Link: https://lore.kernel.org/all/202209050605.fezJUgFH-lkp@intel.com/ Fixes: 87c2a29a6bf1 ("pinctrl: imx8m: kconfig: Depends on SOC_IMX8M") Signed-off-by: Francesco Dolcini Reviewed-by: Jacky Bai Link: https://lore.kernel.org/r/20220905224408.346425-1-francesco.dolcini@toradex.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index 365fcff8e470..7a32f77792d9 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -119,6 +119,7 @@ config PINCTRL_IMX7ULP config PINCTRL_IMX8MM tristate "IMX8MM pinctrl driver" + depends on OF depends on SOC_IMX8M select PINCTRL_IMX help @@ -126,6 +127,7 @@ config PINCTRL_IMX8MM config PINCTRL_IMX8MN tristate "IMX8MN pinctrl driver" + depends on OF depends on SOC_IMX8M select PINCTRL_IMX help @@ -133,6 +135,7 @@ config PINCTRL_IMX8MN config PINCTRL_IMX8MP tristate "IMX8MP pinctrl driver" + depends on OF depends on SOC_IMX8M select PINCTRL_IMX help @@ -140,6 +143,7 @@ config PINCTRL_IMX8MP config PINCTRL_IMX8MQ tristate "IMX8MQ pinctrl driver" + depends on OF depends on SOC_IMX8M select PINCTRL_IMX help From f1509dad5dbf480e3f19fbd99e586d919adf55fe Mon Sep 17 00:00:00 2001 From: Iskren Chernev Date: Sat, 3 Sep 2022 20:41:45 +0300 Subject: [PATCH 131/401] dt-bindings: pinctrl: qcom: sm6115: Add reserved ranges Ideally this and similar common properties will be inherited so you won't need to paste them in every pinctrl binding. Signed-off-by: Iskren Chernev Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20220903174150.3566935-5-iskren.chernev@gmail.com Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml index a7a2bb8bff46..d8443811767d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml @@ -49,6 +49,8 @@ properties: gpio-ranges: maxItems: 1 + gpio-reserved-ranges: true + wakeup-parent: true #PIN CONFIGURATION NODES From 8c943137c00a773ece8d324862910d53832a97a1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 5 Sep 2022 21:51:02 +0300 Subject: [PATCH 132/401] pinctrl: ingenic: Switch to use fwnode instead of of_node GPIO library now accepts fwnode as a firmware node, so switch the driver to use it. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220905185102.74056-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 3a9ee9c8af11..7e732076dedf 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -12,14 +12,14 @@ #include #include #include -#include -#include -#include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -4152,7 +4152,7 @@ static const struct of_device_id ingenic_gpio_of_matches[] __initconst = { }; static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc, - struct device_node *node) + struct fwnode_handle *fwnode) { struct ingenic_gpio_chip *jzgc; struct device *dev = jzpc->dev; @@ -4160,7 +4160,7 @@ static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc, unsigned int bank; int err; - err = of_property_read_u32(node, "reg", &bank); + err = fwnode_property_read_u32(fwnode, "reg", &bank); if (err) { dev_err(dev, "Cannot read \"reg\" property: %i\n", err); return err; @@ -4185,7 +4185,7 @@ static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc, jzgc->gc.ngpio = 32; jzgc->gc.parent = dev; - jzgc->gc.of_node = node; + jzgc->gc.fwnode = fwnode; jzgc->gc.owner = THIS_MODULE; jzgc->gc.set = ingenic_gpio_set; @@ -4196,9 +4196,12 @@ static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc, jzgc->gc.request = gpiochip_generic_request; jzgc->gc.free = gpiochip_generic_free; - jzgc->irq = irq_of_parse_and_map(node, 0); - if (!jzgc->irq) + err = fwnode_irq_get(fwnode, 0); + if (err < 0) + return err; + if (!err) return -EINVAL; + jzgc->irq = err; girq = &jzgc->gc.irq; gpio_irq_chip_set_chip(girq, &ingenic_gpio_irqchip); @@ -4227,12 +4230,12 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) struct pinctrl_desc *pctl_desc; void __iomem *base; const struct ingenic_chip_info *chip_info; - struct device_node *node; struct regmap_config regmap_config; + struct fwnode_handle *fwnode; unsigned int i; int err; - chip_info = of_device_get_match_data(dev); + chip_info = device_get_match_data(dev); if (!chip_info) { dev_err(dev, "Unsupported SoC\n"); return -EINVAL; @@ -4319,11 +4322,11 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) dev_set_drvdata(dev, jzpc->map); - for_each_child_of_node(dev->of_node, node) { - if (of_match_node(ingenic_gpio_of_matches, node)) { - err = ingenic_gpio_probe(jzpc, node); + device_for_each_child_node(dev, fwnode) { + if (of_match_node(ingenic_gpio_of_matches, to_of_node(fwnode))) { + err = ingenic_gpio_probe(jzpc, fwnode); if (err) { - of_node_put(node); + fwnode_handle_put(fwnode); return err; } } From 6323f916686d4e9d299a53114b28ecaf833422cd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 6 Sep 2022 14:50:21 +0300 Subject: [PATCH 133/401] pinctrl: microchip-sgpio: Correct the fwnode_irq_get() return value check fwnode_irq_get() may return all possible signed values, such as Linux error code. Fix the code to handle this properly. Fixes: be2dc859abd4 ("pinctrl: pinctrl-microchip-sgpio: Add irq support (for sparx5)") Signed-off-by: Andy Shevchenko Reviewed-by: Michael Walle Link: https://lore.kernel.org/r/20220906115021.8661-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-microchip-sgpio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c index 6f55bf7d5e05..0771b743a940 100644 --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c @@ -864,9 +864,10 @@ static int microchip_sgpio_register_bank(struct device *dev, gc->can_sleep = !bank->is_input; if (bank->is_input && priv->properties->flags & SGPIO_FLAGS_HAS_IRQ) { - int irq = fwnode_irq_get(fwnode, 0); + int irq; - if (irq) { + irq = fwnode_irq_get(fwnode, 0); + if (irq > 0) { struct gpio_irq_chip *girq = &gc->irq; gpio_irq_chip_set_chip(girq, µchip_sgpio_irqchip); From 827eb27ec2e508e1ef5dc36d29db73cbae1ccb40 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 5 Sep 2022 21:00:34 +0300 Subject: [PATCH 134/401] pinctrl: meson: Switch to use fwnode instead of of_node GPIO library now accepts fwnode as a firmware node, so switch the driver to use it. Signed-off-by: Andy Shevchenko Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20220905180034.73132-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/meson/pinctrl-meson.c | 7 +++---- drivers/pinctrl/meson/pinctrl-meson.h | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index cc2cd73ff8f9..530f3f934e19 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -608,6 +608,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc) pc->chip.label = pc->data->name; pc->chip.parent = pc->dev; + pc->chip.fwnode = pc->fwnode; pc->chip.request = gpiochip_generic_request; pc->chip.free = gpiochip_generic_free; pc->chip.set_config = gpiochip_generic_config; @@ -619,8 +620,6 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc) pc->chip.base = -1; pc->chip.ngpio = pc->data->num_pins; pc->chip.can_sleep = false; - pc->chip.of_node = pc->of_node; - pc->chip.of_gpio_n_cells = 2; ret = gpiochip_add_data(&pc->chip, pc); if (ret) { @@ -678,8 +677,8 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc) return -EINVAL; } - gpio_np = to_of_node(gpiochip_node_get_first(pc->dev)); - pc->of_node = gpio_np; + pc->fwnode = gpiochip_node_get_first(pc->dev); + gpio_np = to_of_node(pc->fwnode); pc->reg_mux = meson_map_resource(pc, gpio_np, "mux"); if (IS_ERR_OR_NULL(pc->reg_mux)) { diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index b197827027bd..34fc4e8612e4 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -12,6 +12,8 @@ #include #include +struct fwnode_handle; + struct meson_pinctrl; /** @@ -131,7 +133,7 @@ struct meson_pinctrl { struct regmap *reg_gpio; struct regmap *reg_ds; struct gpio_chip chip; - struct device_node *of_node; + struct fwnode_handle *fwnode; }; #define FUNCTION(fn) \ From 1a41d1e5c8e5c5850a15abf3d18f610e9310b8ef Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Tue, 30 Aug 2022 14:52:32 +0530 Subject: [PATCH 135/401] pinctrl: qcom: spmi-gpio: Make irqchip immutable The irqchip implementation used inside the gpiochips are not supposed to be changed during runtime. So let's make the one inside the spmi-gpio gpiochip immutable. This fixes the below warning during boot: gpio gpiochip0: (c440000.spmi:pmic@0:gpio@c000): not an immutable chip, please consider fixing it! Acked-by: Marc Zyngier Signed-off-by: Manivannan Sadhasivam Reviewed-by: Johan Hovold Link: https://lore.kernel.org/r/20220830092232.168561-1-manivannan.sadhasivam@linaro.org [switched two lines as indicated by Johan] Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 38 +++++++++++++++++------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index ccaf40a9c0e6..8ba3d5021f0b 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -171,7 +171,6 @@ struct pmic_gpio_state { struct regmap *map; struct pinctrl_dev *ctrl; struct gpio_chip chip; - struct irq_chip irq; u8 usid; u8 pid_base; }; @@ -985,6 +984,33 @@ static int pmic_gpio_populate_parent_fwspec(struct gpio_chip *chip, return 0; } +static void pmic_gpio_irq_mask(struct irq_data *data) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + + irq_chip_mask_parent(data); + gpiochip_disable_irq(gc, data->hwirq); +} + +static void pmic_gpio_irq_unmask(struct irq_data *data) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + + gpiochip_enable_irq(gc, data->hwirq); + irq_chip_unmask_parent(data); +} + +static const struct irq_chip spmi_gpio_irq_chip = { + .name = "spmi-gpio", + .irq_ack = irq_chip_ack_parent, + .irq_mask = pmic_gpio_irq_mask, + .irq_unmask = pmic_gpio_irq_unmask, + .irq_set_type = irq_chip_set_type_parent, + .irq_set_wake = irq_chip_set_wake_parent, + .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static int pmic_gpio_probe(struct platform_device *pdev) { struct irq_domain *parent_domain; @@ -1078,16 +1104,8 @@ static int pmic_gpio_probe(struct platform_device *pdev) if (!parent_domain) return -ENXIO; - state->irq.name = "spmi-gpio", - state->irq.irq_ack = irq_chip_ack_parent, - state->irq.irq_mask = irq_chip_mask_parent, - state->irq.irq_unmask = irq_chip_unmask_parent, - state->irq.irq_set_type = irq_chip_set_type_parent, - state->irq.irq_set_wake = irq_chip_set_wake_parent, - state->irq.flags = IRQCHIP_MASK_ON_SUSPEND, - girq = &state->chip.irq; - girq->chip = &state->irq; + gpio_irq_chip_set_chip(girq, &spmi_gpio_irq_chip); girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_level_irq; girq->fwnode = of_node_to_fwnode(state->dev->of_node); From 88d60d7d94bfab00abef3596fbf54b460c2a45ec Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 8 Sep 2022 12:43:23 +0300 Subject: [PATCH 136/401] pinctrl: pistachio: Correct the fwnode_irq_get() return value check fwnode_irq_get() may return all possible signed values, such as Linux error code or 0. Fix the code to handle this properly. Fixes: 1074e1d23a5c ("pinctrl: pistachio: Switch to use fwnode instead of") Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220908094323.31965-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-pistachio.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pinctrl/pinctrl-pistachio.c b/drivers/pinctrl/pinctrl-pistachio.c index 940ed3fff63a..7ca4ecb6eb8d 100644 --- a/drivers/pinctrl/pinctrl-pistachio.c +++ b/drivers/pinctrl/pinctrl-pistachio.c @@ -1374,8 +1374,14 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl) ret = fwnode_irq_get(child, 0); if (ret < 0) { + fwnode_handle_put(child); + dev_err(pctl->dev, "Failed to retrieve IRQ for bank %u\n", i); + goto err; + } + if (!ret) { fwnode_handle_put(child); dev_err(pctl->dev, "No IRQ for bank %u\n", i); + ret = -EINVAL; goto err; } irq = ret; From e7ed42a44c36351cd064797613d6ae34c0140424 Mon Sep 17 00:00:00 2001 From: wangjianli Date: Thu, 8 Sep 2022 12:37:09 -0700 Subject: [PATCH 137/401] Input: hgpk - fix repeated word in a comment Delete the redundant word 'to'. Signed-off-by: wangjianli Link: https://lore.kernel.org/r/20220908131043.37099-1-wangjianli@cdjrlc.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/hgpk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 523b26a117d6..3c8310da0b05 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -884,7 +884,7 @@ static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data, /* * We queue work instead of doing recalibration right here - * to avoid adding locking to to hgpk_force_recalibrate() + * to avoid adding locking to hgpk_force_recalibrate() * since workqueue provides serialization. */ psmouse_queue_work(psmouse, &priv->recalib_wq, 0); From e662d349ab6601ffaadd3403bca2775c8ffc050d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 8 Sep 2022 17:21:34 +0300 Subject: [PATCH 138/401] pinctrl: cy8c95x0: Use 'default' in all switch-cases (part 2) Move the default values to the 'default' case in the switches. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220908142134.59068-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 1335d07822f9..79f73d364f3f 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -357,9 +357,9 @@ static bool cy8c95x0_volatile_register(struct device *dev, unsigned int reg) case CY8C95X0_DRV_PP_SLOW: case CY8C95X0_DRV_HIZ: return true; + default: + return false; } - - return false; } static bool cy8c95x0_precious_register(struct device *dev, unsigned int reg) From 80d98a33008cbfd9ed0271b0e253ff88b51f96ac Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Fri, 9 Sep 2022 20:31:39 -0500 Subject: [PATCH 139/401] ipmi:ipmb: Don't call ipmi_unregister_smi() on a register failure The data structure won't be set up to be unregistered, and it can result in crashes if the register fails. Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_ipmb.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ipmb.c b/drivers/char/ipmi/ipmi_ipmb.c index 1019946abe4e..740dc0f824e0 100644 --- a/drivers/char/ipmi/ipmi_ipmb.c +++ b/drivers/char/ipmi/ipmi_ipmb.c @@ -424,10 +424,8 @@ static void ipmi_ipmb_request_events(void *send_info) /* We don't fetch events here. */ } -static int ipmi_ipmb_remove(struct i2c_client *client) +static void ipmi_ipmb_cleanup(struct ipmi_ipmb_dev *iidev) { - struct ipmi_ipmb_dev *iidev = i2c_get_clientdata(client); - if (iidev->slave) { i2c_slave_unregister(iidev->slave); if (iidev->slave != iidev->client) @@ -436,7 +434,13 @@ static int ipmi_ipmb_remove(struct i2c_client *client) iidev->slave = NULL; iidev->client = NULL; ipmi_ipmb_stop_thread(iidev); +} +static int ipmi_ipmb_remove(struct i2c_client *client) +{ + struct ipmi_ipmb_dev *iidev = i2c_get_clientdata(client); + + ipmi_ipmb_cleanup(iidev); ipmi_unregister_smi(iidev->intf); return 0; @@ -544,7 +548,7 @@ static int ipmi_ipmb_probe(struct i2c_client *client) out_err: if (slave && slave != client) i2c_unregister_device(slave); - ipmi_ipmb_remove(client); + ipmi_ipmb_cleanup(iidev); return rv; } From a47126ec29f538e1197862919f94d3b6668144a4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:24:57 -0500 Subject: [PATCH 140/401] PCI/PTM: Cache PTM Capability offset Cache the PTM Capability offset instead of searching for it every time we enable/disable PTM or save/restore PTM state. No functional change intended. Link: https://lore.kernel.org/r/20220909202505.314195-2-helgaas@kernel.org Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Kuppuswamy Sathyanarayanan Reviewed-by: Mika Westerberg --- drivers/pci/pcie/ptm.c | 41 +++++++++++++++++------------------------ include/linux/pci.h | 1 + 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index 368a254e3124..85382c135885 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -31,13 +31,9 @@ static void pci_ptm_info(struct pci_dev *dev) void pci_disable_ptm(struct pci_dev *dev) { - int ptm; + u16 ptm = dev->ptm_cap; u16 ctrl; - if (!pci_is_pcie(dev)) - return; - - ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); if (!ptm) return; @@ -48,14 +44,10 @@ void pci_disable_ptm(struct pci_dev *dev) void pci_save_ptm_state(struct pci_dev *dev) { - int ptm; + u16 ptm = dev->ptm_cap; struct pci_cap_saved_state *save_state; u16 *cap; - if (!pci_is_pcie(dev)) - return; - - ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); if (!ptm) return; @@ -69,16 +61,15 @@ void pci_save_ptm_state(struct pci_dev *dev) void pci_restore_ptm_state(struct pci_dev *dev) { + u16 ptm = dev->ptm_cap; struct pci_cap_saved_state *save_state; - int ptm; u16 *cap; - if (!pci_is_pcie(dev)) + if (!ptm) return; save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_PTM); - ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); - if (!save_state || !ptm) + if (!save_state) return; cap = (u16 *)&save_state->cap.data[0]; @@ -87,7 +78,7 @@ void pci_restore_ptm_state(struct pci_dev *dev) void pci_ptm_init(struct pci_dev *dev) { - int pos; + u16 ptm; u32 cap, ctrl; u8 local_clock; struct pci_dev *ups; @@ -117,13 +108,14 @@ void pci_ptm_init(struct pci_dev *dev) return; } - pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); - if (!pos) + ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); + if (!ptm) return; + dev->ptm_cap = ptm; pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_PTM, sizeof(u16)); - pci_read_config_dword(dev, pos + PCI_PTM_CAP, &cap); + pci_read_config_dword(dev, ptm + PCI_PTM_CAP, &cap); local_clock = (cap & PCI_PTM_GRANULARITY_MASK) >> 8; /* @@ -148,7 +140,7 @@ void pci_ptm_init(struct pci_dev *dev) } ctrl |= dev->ptm_granularity << 8; - pci_write_config_dword(dev, pos + PCI_PTM_CTRL, ctrl); + pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); dev->ptm_enabled = 1; pci_ptm_info(dev); @@ -156,18 +148,19 @@ void pci_ptm_init(struct pci_dev *dev) int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) { - int pos; + u16 ptm; u32 cap, ctrl; struct pci_dev *ups; if (!pci_is_pcie(dev)) return -EINVAL; - pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); - if (!pos) + ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); + if (!ptm) return -EINVAL; - pci_read_config_dword(dev, pos + PCI_PTM_CAP, &cap); + dev->ptm_cap = ptm; + pci_read_config_dword(dev, ptm + PCI_PTM_CAP, &cap); if (!(cap & PCI_PTM_CAP_REQ)) return -EINVAL; @@ -192,7 +185,7 @@ int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) ctrl = PCI_PTM_CTRL_ENABLE; ctrl |= dev->ptm_granularity << 8; - pci_write_config_dword(dev, pos + PCI_PTM_CTRL, ctrl); + pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); dev->ptm_enabled = 1; pci_ptm_info(dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 060af91bafcd..54be939023a3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -475,6 +475,7 @@ struct pci_dev { unsigned int broken_cmd_compl:1; /* No compl for some cmds */ #endif #ifdef CONFIG_PCIE_PTM + u16 ptm_cap; /* PTM Capability */ unsigned int ptm_root:1; unsigned int ptm_enabled:1; u8 ptm_granularity; From e243c173c015d62b2bca9b030777ceba13311033 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:24:58 -0500 Subject: [PATCH 141/401] PCI/PTM: Add pci_upstream_ptm() helper PTM requires an unbroken path of PTM-supporting devices between the PTM Root and the ultimate PTM Requester, but if a Switch supports PTM, only the Upstream Port can have a PTM Capability; the Downstream Ports do not. Previously we copied the PTM configuration from the Switch Upstream Port to the Downstream Ports so dev->ptm_enabled for any device implied that all the upstream devices support PTM. Instead of making it look like Downstream Ports have their own PTM config, add pci_upstream_ptm(), which returns the upstream device that has a PTM Capability (either a Root Port or a Switch Upstream Port). Link: https://lore.kernel.org/r/20220909202505.314195-3-helgaas@kernel.org Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Kuppuswamy Sathyanarayanan Reviewed-by: Mika Westerberg --- drivers/pci/pcie/ptm.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index 85382c135885..0df6cdfe38b4 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -76,6 +76,29 @@ void pci_restore_ptm_state(struct pci_dev *dev) pci_write_config_word(dev, ptm + PCI_PTM_CTRL, *cap); } +/* + * If the next upstream device supports PTM, return it; otherwise return + * NULL. PTM Messages are local, so both link partners must support it. + */ +static struct pci_dev *pci_upstream_ptm(struct pci_dev *dev) +{ + struct pci_dev *ups = pci_upstream_bridge(dev); + + /* + * Switch Downstream Ports are not permitted to have a PTM + * capability; their PTM behavior is controlled by the Upstream + * Port (PCIe r5.0, sec 7.9.16), so if the upstream bridge is a + * Switch Downstream Port, look up one more level. + */ + if (ups && pci_pcie_type(ups) == PCI_EXP_TYPE_DOWNSTREAM) + ups = pci_upstream_bridge(ups); + + if (ups && ups->ptm_cap) + return ups; + + return NULL; +} + void pci_ptm_init(struct pci_dev *dev) { u16 ptm; @@ -95,19 +118,6 @@ void pci_ptm_init(struct pci_dev *dev) pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)) return; - /* - * Switch Downstream Ports are not permitted to have a PTM - * capability; their PTM behavior is controlled by the Upstream - * Port (PCIe r5.0, sec 7.9.16). - */ - ups = pci_upstream_bridge(dev); - if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM && - ups && ups->ptm_enabled) { - dev->ptm_granularity = ups->ptm_granularity; - dev->ptm_enabled = 1; - return; - } - ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); if (!ptm) return; @@ -124,6 +134,7 @@ void pci_ptm_init(struct pci_dev *dev) * the spec recommendation (PCIe r3.1, sec 7.32.3), select the * furthest upstream Time Source as the PTM Root. */ + ups = pci_upstream_ptm(dev); if (ups && ups->ptm_enabled) { ctrl = PCI_PTM_CTRL_ENABLE; if (ups->ptm_granularity == 0) @@ -173,7 +184,7 @@ int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) * associate the endpoint with a time source. */ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ENDPOINT) { - ups = pci_upstream_bridge(dev); + ups = pci_upstream_ptm(dev); if (!ups || !ups->ptm_enabled) return -EINVAL; From 118b9dfdc18b68abf736a71330e3ad1f5af7e47e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:24:59 -0500 Subject: [PATCH 142/401] PCI/PTM: Separate configuration and enable PTM configuration and enabling were previously mixed together: pci_ptm_init() collected granularity info and enabled PTM for Root Ports and Switch Upstream Ports; pci_enable_ptm() did the same for Endpoints. Move everything related to the PTM Capability register to pci_ptm_init() for all devices, and everything related to the PTM Control register to pci_enable_ptm(). Link: https://lore.kernel.org/r/20220909202505.314195-4-helgaas@kernel.org Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg --- drivers/pci/pcie/ptm.c | 104 +++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 55 deletions(-) diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index 0df6cdfe38b4..ba1d50c965fa 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -99,25 +99,19 @@ static struct pci_dev *pci_upstream_ptm(struct pci_dev *dev) return NULL; } +/* + * Find the PTM Capability (if present) and extract the information we need + * to use it. + */ void pci_ptm_init(struct pci_dev *dev) { u16 ptm; - u32 cap, ctrl; - u8 local_clock; + u32 cap; struct pci_dev *ups; if (!pci_is_pcie(dev)) return; - /* - * Enable PTM only on interior devices (root ports, switch ports, - * etc.) on the assumption that it causes no link traffic until an - * endpoint enables it. - */ - if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ENDPOINT || - pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)) - return; - ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); if (!ptm) return; @@ -126,76 +120,76 @@ void pci_ptm_init(struct pci_dev *dev) pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_PTM, sizeof(u16)); pci_read_config_dword(dev, ptm + PCI_PTM_CAP, &cap); - local_clock = (cap & PCI_PTM_GRANULARITY_MASK) >> 8; + dev->ptm_granularity = (cap & PCI_PTM_GRANULARITY_MASK) >> 8; /* - * There's no point in enabling PTM unless it's enabled in the - * upstream device or this device can be a PTM Root itself. Per - * the spec recommendation (PCIe r3.1, sec 7.32.3), select the - * furthest upstream Time Source as the PTM Root. + * Per the spec recommendation (PCIe r6.0, sec 7.9.15.3), select the + * furthest upstream Time Source as the PTM Root. For Endpoints, + * "the Effective Granularity is the maximum Local Clock Granularity + * reported by the PTM Root and all intervening PTM Time Sources." */ ups = pci_upstream_ptm(dev); - if (ups && ups->ptm_enabled) { - ctrl = PCI_PTM_CTRL_ENABLE; + if (ups) { if (ups->ptm_granularity == 0) dev->ptm_granularity = 0; - else if (ups->ptm_granularity > local_clock) + else if (ups->ptm_granularity > dev->ptm_granularity) dev->ptm_granularity = ups->ptm_granularity; - } else { - if (cap & PCI_PTM_CAP_ROOT) { - ctrl = PCI_PTM_CTRL_ENABLE | PCI_PTM_CTRL_ROOT; - dev->ptm_root = 1; - dev->ptm_granularity = local_clock; - } else - return; + } else if (cap & PCI_PTM_CAP_ROOT) { + dev->ptm_root = 1; + } else if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) { + + /* + * Per sec 7.9.15.3, this should be the Local Clock + * Granularity of the associated Time Source. But it + * doesn't say how to find that Time Source. + */ + dev->ptm_granularity = 0; } - ctrl |= dev->ptm_granularity << 8; - pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); - dev->ptm_enabled = 1; - - pci_ptm_info(dev); + if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT || + pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) + pci_enable_ptm(dev, NULL); } +/** + * pci_enable_ptm() - Enable Precision Time Measurement + * @dev: PCI device + * @granularity: pointer to return granularity + * + * Enable Precision Time Measurement for @dev. If successful and + * @granularity is non-NULL, return the Effective Granularity. + * + * Return: zero if successful, or -EINVAL if @dev lacks a PTM Capability or + * is not a PTM Root and lacks an upstream path of PTM-enabled devices. + */ int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) { - u16 ptm; - u32 cap, ctrl; + u16 ptm = dev->ptm_cap; struct pci_dev *ups; + u32 ctrl; - if (!pci_is_pcie(dev)) - return -EINVAL; - - ptm = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); if (!ptm) return -EINVAL; - dev->ptm_cap = ptm; - pci_read_config_dword(dev, ptm + PCI_PTM_CAP, &cap); - if (!(cap & PCI_PTM_CAP_REQ)) - return -EINVAL; - /* - * For a PCIe Endpoint, PTM is only useful if the endpoint can - * issue PTM requests to upstream devices that have PTM enabled. - * - * For Root Complex Integrated Endpoints, there is no upstream - * device, so there must be some implementation-specific way to - * associate the endpoint with a time source. + * A device uses local PTM Messages to request time information + * from a PTM Root that's farther upstream. Every device along the + * path must support PTM and have it enabled so it can handle the + * messages. Therefore, if this device is not a PTM Root, the + * upstream link partner must have PTM enabled before we can enable + * PTM. */ - if (pci_pcie_type(dev) == PCI_EXP_TYPE_ENDPOINT) { + if (!dev->ptm_root) { ups = pci_upstream_ptm(dev); if (!ups || !ups->ptm_enabled) return -EINVAL; - - dev->ptm_granularity = ups->ptm_granularity; - } else if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) { - dev->ptm_granularity = 0; - } else - return -EINVAL; + } ctrl = PCI_PTM_CTRL_ENABLE; ctrl |= dev->ptm_granularity << 8; + if (dev->ptm_root) + ctrl |= PCI_PTM_CTRL_ROOT; + pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); dev->ptm_enabled = 1; From e8bdc5ea481638e0a4fd5639050d2b170417f493 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:25:00 -0500 Subject: [PATCH 143/401] PCI/PTM: Add pci_suspend_ptm() and pci_resume_ptm() We disable PTM during suspend because that allows some Root Ports to enter lower-power PM states, which means we also need to disable PTM for all downstream devices. Add pci_suspend_ptm() and pci_resume_ptm() for this purpose. pci_enable_ptm() and pci_disable_ptm() are for drivers to use to enable or disable PTM. They use dev->ptm_enabled to keep track of whether PTM should be enabled. pci_suspend_ptm() and pci_resume_ptm() are PCI core-internal functions to temporarily disable PTM during suspend and (depending on dev->ptm_enabled) re-enable PTM during resume. Enable/disable/suspend/resume all use internal __pci_enable_ptm() and __pci_disable_ptm() functions that only update the PTM Control register. Outline: pci_enable_ptm(struct pci_dev *dev) { __pci_enable_ptm(dev); dev->ptm_enabled = 1; pci_ptm_info(dev); } pci_disable_ptm(struct pci_dev *dev) { if (dev->ptm_enabled) { __pci_disable_ptm(dev); dev->ptm_enabled = 0; } } pci_suspend_ptm(struct pci_dev *dev) { if (dev->ptm_enabled) __pci_disable_ptm(dev); } pci_resume_ptm(struct pci_dev *dev) { if (dev->ptm_enabled) __pci_enable_ptm(dev); } Nothing currently calls pci_resume_ptm(); the suspend path saves the PTM state before disabling PTM, so the PTM state restore in the resume path implicitly re-enables it. A future change will use pci_resume_ptm() to fix some problems with this approach. Link: https://lore.kernel.org/r/20220909202505.314195-5-helgaas@kernel.org Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg --- drivers/pci/pci.c | 4 +-- drivers/pci/pci.h | 6 ++-- drivers/pci/pcie/ptm.c | 71 +++++++++++++++++++++++++++++++++--------- include/linux/pci.h | 2 ++ 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 95bc329e74c0..83818f81577d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2714,7 +2714,7 @@ int pci_prepare_to_sleep(struct pci_dev *dev) * lower-power idle state as a whole. */ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) - pci_disable_ptm(dev); + pci_suspend_ptm(dev); pci_enable_wake(dev, target_state, wakeup); @@ -2772,7 +2772,7 @@ int pci_finish_runtime_suspend(struct pci_dev *dev) * lower-power idle state as a whole. */ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) - pci_disable_ptm(dev); + pci_suspend_ptm(dev); __pci_enable_wake(dev, target_state, pci_dev_run_wake(dev)); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 785f31086313..ce4a277e3f41 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -507,11 +507,13 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) #ifdef CONFIG_PCIE_PTM void pci_save_ptm_state(struct pci_dev *dev); void pci_restore_ptm_state(struct pci_dev *dev); -void pci_disable_ptm(struct pci_dev *dev); +void pci_suspend_ptm(struct pci_dev *dev); +void pci_resume_ptm(struct pci_dev *dev); #else static inline void pci_save_ptm_state(struct pci_dev *dev) { } static inline void pci_restore_ptm_state(struct pci_dev *dev) { } -static inline void pci_disable_ptm(struct pci_dev *dev) { } +static inline void pci_suspend_ptm(struct pci_dev *dev) { } +static inline void pci_resume_ptm(struct pci_dev *dev) { } #endif unsigned long pci_cardbus_resource_alignment(struct resource *); diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index ba1d50c965fa..70a28b74e721 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -29,7 +29,7 @@ static void pci_ptm_info(struct pci_dev *dev) dev->ptm_root ? " (root)" : "", clock_desc); } -void pci_disable_ptm(struct pci_dev *dev) +static void __pci_disable_ptm(struct pci_dev *dev) { u16 ptm = dev->ptm_cap; u16 ctrl; @@ -42,6 +42,21 @@ void pci_disable_ptm(struct pci_dev *dev) pci_write_config_word(dev, ptm + PCI_PTM_CTRL, ctrl); } +/** + * pci_disable_ptm() - Disable Precision Time Measurement + * @dev: PCI device + * + * Disable Precision Time Measurement for @dev. + */ +void pci_disable_ptm(struct pci_dev *dev) +{ + if (dev->ptm_enabled) { + __pci_disable_ptm(dev); + dev->ptm_enabled = 0; + } +} +EXPORT_SYMBOL(pci_disable_ptm); + void pci_save_ptm_state(struct pci_dev *dev) { u16 ptm = dev->ptm_cap; @@ -151,18 +166,8 @@ void pci_ptm_init(struct pci_dev *dev) pci_enable_ptm(dev, NULL); } -/** - * pci_enable_ptm() - Enable Precision Time Measurement - * @dev: PCI device - * @granularity: pointer to return granularity - * - * Enable Precision Time Measurement for @dev. If successful and - * @granularity is non-NULL, return the Effective Granularity. - * - * Return: zero if successful, or -EINVAL if @dev lacks a PTM Capability or - * is not a PTM Root and lacks an upstream path of PTM-enabled devices. - */ -int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) +/* Enable PTM in the Control register if possible */ +static int __pci_enable_ptm(struct pci_dev *dev) { u16 ptm = dev->ptm_cap; struct pci_dev *ups; @@ -191,8 +196,29 @@ int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) ctrl |= PCI_PTM_CTRL_ROOT; pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); - dev->ptm_enabled = 1; + return 0; +} +/** + * pci_enable_ptm() - Enable Precision Time Measurement + * @dev: PCI device + * @granularity: pointer to return granularity + * + * Enable Precision Time Measurement for @dev. If successful and + * @granularity is non-NULL, return the Effective Granularity. + * + * Return: zero if successful, or -EINVAL if @dev lacks a PTM Capability or + * is not a PTM Root and lacks an upstream path of PTM-enabled devices. + */ +int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) +{ + int rc; + + rc = __pci_enable_ptm(dev); + if (rc) + return rc; + + dev->ptm_enabled = 1; pci_ptm_info(dev); if (granularity) @@ -201,6 +227,23 @@ int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) } EXPORT_SYMBOL(pci_enable_ptm); +/* + * Disable PTM, but preserve dev->ptm_enabled so we silently re-enable it on + * resume if necessary. + */ +void pci_suspend_ptm(struct pci_dev *dev) +{ + if (dev->ptm_enabled) + __pci_disable_ptm(dev); +} + +/* If PTM was enabled before suspend, re-enable it when resuming */ +void pci_resume_ptm(struct pci_dev *dev) +{ + if (dev->ptm_enabled) + __pci_enable_ptm(dev); +} + bool pcie_ptm_enabled(struct pci_dev *dev) { if (!dev) diff --git a/include/linux/pci.h b/include/linux/pci.h index 54be939023a3..cb5f796e3319 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1678,10 +1678,12 @@ bool pci_ats_disabled(void); #ifdef CONFIG_PCIE_PTM int pci_enable_ptm(struct pci_dev *dev, u8 *granularity); +void pci_disable_ptm(struct pci_dev *dev); bool pcie_ptm_enabled(struct pci_dev *dev); #else static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) { return -EINVAL; } +static inline void pci_disable_ptm(struct pci_dev *dev) { } static inline bool pcie_ptm_enabled(struct pci_dev *dev) { return false; } #endif From 91b12b2a100e977274d3c277a4ff2df0b7439e7d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:25:01 -0500 Subject: [PATCH 144/401] PCI/PTM: Move pci_ptm_info() body into its only caller pci_ptm_info() is simple and is only called by pci_enable_ptm(). Move the entire body there. No functional change intended. Link: https://lore.kernel.org/r/20220909202505.314195-6-helgaas@kernel.org Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Kuppuswamy Sathyanarayanan Reviewed-by: Mika Westerberg --- drivers/pci/pcie/ptm.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index 70a28b74e721..fc296b352fe2 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -9,26 +9,6 @@ #include #include "../pci.h" -static void pci_ptm_info(struct pci_dev *dev) -{ - char clock_desc[8]; - - switch (dev->ptm_granularity) { - case 0: - snprintf(clock_desc, sizeof(clock_desc), "unknown"); - break; - case 255: - snprintf(clock_desc, sizeof(clock_desc), ">254ns"); - break; - default: - snprintf(clock_desc, sizeof(clock_desc), "%uns", - dev->ptm_granularity); - break; - } - pci_info(dev, "PTM enabled%s, %s granularity\n", - dev->ptm_root ? " (root)" : "", clock_desc); -} - static void __pci_disable_ptm(struct pci_dev *dev) { u16 ptm = dev->ptm_cap; @@ -213,16 +193,32 @@ static int __pci_enable_ptm(struct pci_dev *dev) int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) { int rc; + char clock_desc[8]; rc = __pci_enable_ptm(dev); if (rc) return rc; dev->ptm_enabled = 1; - pci_ptm_info(dev); if (granularity) *granularity = dev->ptm_granularity; + + switch (dev->ptm_granularity) { + case 0: + snprintf(clock_desc, sizeof(clock_desc), "unknown"); + break; + case 255: + snprintf(clock_desc, sizeof(clock_desc), ">254ns"); + break; + default: + snprintf(clock_desc, sizeof(clock_desc), "%uns", + dev->ptm_granularity); + break; + } + pci_info(dev, "PTM enabled%s, %s granularity\n", + dev->ptm_root ? " (root)" : "", clock_desc); + return 0; } EXPORT_SYMBOL(pci_enable_ptm); From 2b89c22f2434b931b3cf22298ac5f5ec089e9ad1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:25:02 -0500 Subject: [PATCH 145/401] PCI/PTM: Preserve RsvdP bits in PTM Control register Even though only the low 16 bits of PTM Control are currently defined, the register is 32 bits wide and the unused bits are RsvdP ("Reserved and Preserved"), so software must preserve the values of those bits when writing the register. Update PTM Control reads and writes to use 32-bit accesses and preserve the reserved bits on writes. Link: https://lore.kernel.org/r/20220909202505.314195-7-helgaas@kernel.org Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Kuppuswamy Sathyanarayanan Reviewed-by: Mika Westerberg --- drivers/pci/pcie/ptm.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index fc296b352fe2..5b8598b222b0 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -12,14 +12,14 @@ static void __pci_disable_ptm(struct pci_dev *dev) { u16 ptm = dev->ptm_cap; - u16 ctrl; + u32 ctrl; if (!ptm) return; - pci_read_config_word(dev, ptm + PCI_PTM_CTRL, &ctrl); + pci_read_config_dword(dev, ptm + PCI_PTM_CTRL, &ctrl); ctrl &= ~(PCI_PTM_CTRL_ENABLE | PCI_PTM_CTRL_ROOT); - pci_write_config_word(dev, ptm + PCI_PTM_CTRL, ctrl); + pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); } /** @@ -41,7 +41,7 @@ void pci_save_ptm_state(struct pci_dev *dev) { u16 ptm = dev->ptm_cap; struct pci_cap_saved_state *save_state; - u16 *cap; + u32 *cap; if (!ptm) return; @@ -50,15 +50,15 @@ void pci_save_ptm_state(struct pci_dev *dev) if (!save_state) return; - cap = (u16 *)&save_state->cap.data[0]; - pci_read_config_word(dev, ptm + PCI_PTM_CTRL, cap); + cap = (u32 *)&save_state->cap.data[0]; + pci_read_config_dword(dev, ptm + PCI_PTM_CTRL, cap); } void pci_restore_ptm_state(struct pci_dev *dev) { u16 ptm = dev->ptm_cap; struct pci_cap_saved_state *save_state; - u16 *cap; + u32 *cap; if (!ptm) return; @@ -67,8 +67,8 @@ void pci_restore_ptm_state(struct pci_dev *dev) if (!save_state) return; - cap = (u16 *)&save_state->cap.data[0]; - pci_write_config_word(dev, ptm + PCI_PTM_CTRL, *cap); + cap = (u32 *)&save_state->cap.data[0]; + pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, *cap); } /* @@ -112,7 +112,7 @@ void pci_ptm_init(struct pci_dev *dev) return; dev->ptm_cap = ptm; - pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_PTM, sizeof(u16)); + pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_PTM, sizeof(u32)); pci_read_config_dword(dev, ptm + PCI_PTM_CAP, &cap); dev->ptm_granularity = (cap & PCI_PTM_GRANULARITY_MASK) >> 8; @@ -170,7 +170,10 @@ static int __pci_enable_ptm(struct pci_dev *dev) return -EINVAL; } - ctrl = PCI_PTM_CTRL_ENABLE; + pci_read_config_dword(dev, ptm + PCI_PTM_CTRL, &ctrl); + + ctrl |= PCI_PTM_CTRL_ENABLE; + ctrl &= ~PCI_PTM_GRANULARITY_MASK; ctrl |= dev->ptm_granularity << 8; if (dev->ptm_root) ctrl |= PCI_PTM_CTRL_ROOT; From 8b367e75ac482486bbfd1ca832734bec64498f73 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:25:03 -0500 Subject: [PATCH 146/401] PCI/PTM: Reorder functions in logical order pci_enable_ptm() and pci_disable_ptm() were separated. pci_save_ptm_state() and pci_restore_ptm_state() dangled at the top. Move them to logical places. No functional change intended. Link: https://lore.kernel.org/r/20220909202505.314195-8-helgaas@kernel.org Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg --- drivers/pci/pcie/ptm.c | 124 ++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index 5b8598b222b0..b4e5f553467c 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -9,68 +9,6 @@ #include #include "../pci.h" -static void __pci_disable_ptm(struct pci_dev *dev) -{ - u16 ptm = dev->ptm_cap; - u32 ctrl; - - if (!ptm) - return; - - pci_read_config_dword(dev, ptm + PCI_PTM_CTRL, &ctrl); - ctrl &= ~(PCI_PTM_CTRL_ENABLE | PCI_PTM_CTRL_ROOT); - pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); -} - -/** - * pci_disable_ptm() - Disable Precision Time Measurement - * @dev: PCI device - * - * Disable Precision Time Measurement for @dev. - */ -void pci_disable_ptm(struct pci_dev *dev) -{ - if (dev->ptm_enabled) { - __pci_disable_ptm(dev); - dev->ptm_enabled = 0; - } -} -EXPORT_SYMBOL(pci_disable_ptm); - -void pci_save_ptm_state(struct pci_dev *dev) -{ - u16 ptm = dev->ptm_cap; - struct pci_cap_saved_state *save_state; - u32 *cap; - - if (!ptm) - return; - - save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_PTM); - if (!save_state) - return; - - cap = (u32 *)&save_state->cap.data[0]; - pci_read_config_dword(dev, ptm + PCI_PTM_CTRL, cap); -} - -void pci_restore_ptm_state(struct pci_dev *dev) -{ - u16 ptm = dev->ptm_cap; - struct pci_cap_saved_state *save_state; - u32 *cap; - - if (!ptm) - return; - - save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_PTM); - if (!save_state) - return; - - cap = (u32 *)&save_state->cap.data[0]; - pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, *cap); -} - /* * If the next upstream device supports PTM, return it; otherwise return * NULL. PTM Messages are local, so both link partners must support it. @@ -146,6 +84,40 @@ void pci_ptm_init(struct pci_dev *dev) pci_enable_ptm(dev, NULL); } +void pci_save_ptm_state(struct pci_dev *dev) +{ + u16 ptm = dev->ptm_cap; + struct pci_cap_saved_state *save_state; + u32 *cap; + + if (!ptm) + return; + + save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_PTM); + if (!save_state) + return; + + cap = (u32 *)&save_state->cap.data[0]; + pci_read_config_dword(dev, ptm + PCI_PTM_CTRL, cap); +} + +void pci_restore_ptm_state(struct pci_dev *dev) +{ + u16 ptm = dev->ptm_cap; + struct pci_cap_saved_state *save_state; + u32 *cap; + + if (!ptm) + return; + + save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_PTM); + if (!save_state) + return; + + cap = (u32 *)&save_state->cap.data[0]; + pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, *cap); +} + /* Enable PTM in the Control register if possible */ static int __pci_enable_ptm(struct pci_dev *dev) { @@ -226,6 +198,34 @@ int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) } EXPORT_SYMBOL(pci_enable_ptm); +static void __pci_disable_ptm(struct pci_dev *dev) +{ + u16 ptm = dev->ptm_cap; + u32 ctrl; + + if (!ptm) + return; + + pci_read_config_dword(dev, ptm + PCI_PTM_CTRL, &ctrl); + ctrl &= ~(PCI_PTM_CTRL_ENABLE | PCI_PTM_CTRL_ROOT); + pci_write_config_dword(dev, ptm + PCI_PTM_CTRL, ctrl); +} + +/** + * pci_disable_ptm() - Disable Precision Time Measurement + * @dev: PCI device + * + * Disable Precision Time Measurement for @dev. + */ +void pci_disable_ptm(struct pci_dev *dev) +{ + if (dev->ptm_enabled) { + __pci_disable_ptm(dev); + dev->ptm_enabled = 0; + } +} +EXPORT_SYMBOL(pci_disable_ptm); + /* * Disable PTM, but preserve dev->ptm_enabled so we silently re-enable it on * resume if necessary. From d736d292bba2c5225cb76cd4e04d0e9d00f22498 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:25:04 -0500 Subject: [PATCH 147/401] PCI/PTM: Consolidate PTM interface declarations Consolidate all the PTM-related declarations in drivers/pci/pci.h. No functional change intended. Link: https://lore.kernel.org/r/20220909202505.314195-9-helgaas@kernel.org Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg --- drivers/pci/pci.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index ce4a277e3f41..5cca2e58cce8 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -505,11 +505,13 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) #endif /* CONFIG_PCI_IOV */ #ifdef CONFIG_PCIE_PTM +void pci_ptm_init(struct pci_dev *dev); void pci_save_ptm_state(struct pci_dev *dev); void pci_restore_ptm_state(struct pci_dev *dev); void pci_suspend_ptm(struct pci_dev *dev); void pci_resume_ptm(struct pci_dev *dev); #else +static inline void pci_ptm_init(struct pci_dev *dev) { } static inline void pci_save_ptm_state(struct pci_dev *dev) { } static inline void pci_restore_ptm_state(struct pci_dev *dev) { } static inline void pci_suspend_ptm(struct pci_dev *dev) { } @@ -577,12 +579,6 @@ static inline void pcie_set_ecrc_checking(struct pci_dev *dev) { } static inline void pcie_ecrc_get_policy(char *str) { } #endif -#ifdef CONFIG_PCIE_PTM -void pci_ptm_init(struct pci_dev *dev); -#else -static inline void pci_ptm_init(struct pci_dev *dev) { } -#endif - struct pci_dev_reset_methods { u16 vendor; u16 device; From c01163dbd1b8aa016c163ff4bf3a2e90311504f1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 9 Sep 2022 15:25:05 -0500 Subject: [PATCH 148/401] PCI/PM: Always disable PTM for all devices during suspend We want to disable PTM on Root Ports because that allows some chips, e.g., Intel mobile chips since Coffee Lake, to enter a lower-power PM state. That means we also have to disable PTM on downstream devices. PCIe r6.0, sec 2.2.8, recommends that functions support generation of messages in non-D0 states, so we have to assume Switch Upstream Ports or Endpoints may send PTM Requests while in D1, D2, and D3hot. A PTM message received by a Downstream Port (including a Root Port) with PTM disabled must be treated as an Unsupported Request (sec 6.21.3). PTM was previously disabled only for Root Ports, and it was disabled in pci_prepare_to_sleep(), which is not called at all if a driver supports legacy PM or does its own state saving. Instead, disable PTM early in pci_pm_suspend() and pci_pm_runtime_suspend() so we do it in all cases. Previously PTM was disabled *after* saving device state, so the state restore on resume automatically re-enabled it. Since we now disable PTM *before* saving state, we must explicitly re-enable it in pci_pm_resume() and pci_pm_runtime_resume(). Here's a sample of errors that occur when PTM is disabled only on the Root Port. With this topology: 0000:00:1d.0 Root Port to [bus 08-71] 0000:08:00.0 Switch Upstream Port to [bus 09-71] Kai-Heng reported errors like this: pcieport 0000:00:1d.0: [20] UnsupReq (First) pcieport 0000:00:1d.0: AER: TLP Header: 34000000 08000052 00000000 00000000 Decoding TLP header 0x34...... (0011 0100b) and 0x08000052: Fmt 001b 4 DW header, no data Type 1 0100b Msg (Local - Terminate at Receiver) Requester ID 0x0800 Bus 08 Devfn 00.0 Message Code 0x52 0101 0010b PTM Request The 00:1d.0 Root Port logged an Unsupported Request error when it received a PTM Request with Requester ID 08:00.0. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=215453 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216210 Fixes: a697f072f5da ("PCI: Disable PTM during suspend to save power") Link: https://lore.kernel.org/r/20220909202505.314195-10-helgaas@kernel.org Reported-by: Kai-Heng Feng Tested-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg --- drivers/pci/pci-driver.c | 11 +++++++++++ drivers/pci/pci.c | 28 ++-------------------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 49238ddd39ee..5d8c37c3e15a 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -774,6 +774,12 @@ static int pci_pm_suspend(struct device *dev) pci_dev->skip_bus_pm = false; + /* + * Disabling PTM allows some systems, e.g., Intel mobile chips + * since Coffee Lake, to enter a lower-power PM state. + */ + pci_suspend_ptm(pci_dev); + if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend(dev, PMSG_SUSPEND); @@ -987,6 +993,8 @@ static int pci_pm_resume(struct device *dev) if (pci_dev->state_saved) pci_restore_standard_config(pci_dev); + pci_resume_ptm(pci_dev); + if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume(dev); @@ -1274,6 +1282,8 @@ static int pci_pm_runtime_suspend(struct device *dev) pci_power_t prev = pci_dev->current_state; int error; + pci_suspend_ptm(pci_dev); + /* * If pci_dev->driver is not set (unbound), we leave the device in D0, * but it may go to D3cold when the bridge above it runtime suspends. @@ -1335,6 +1345,7 @@ static int pci_pm_runtime_resume(struct device *dev) * D3cold when the bridge above it runtime suspended. */ pci_pm_default_resume_early(pci_dev); + pci_resume_ptm(pci_dev); if (!pci_dev->driver) return 0; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 83818f81577d..107afa0a5b03 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2706,24 +2706,12 @@ int pci_prepare_to_sleep(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; - /* - * There are systems (for example, Intel mobile chips since Coffee - * Lake) where the power drawn while suspended can be significantly - * reduced by disabling PTM on PCIe root ports as this allows the - * port to enter a lower-power PM state and the SoC to reach a - * lower-power idle state as a whole. - */ - if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) - pci_suspend_ptm(dev); - pci_enable_wake(dev, target_state, wakeup); error = pci_set_power_state(dev, target_state); - if (error) { + if (error) pci_enable_wake(dev, target_state, false); - pci_restore_ptm_state(dev); - } return error; } @@ -2764,24 +2752,12 @@ int pci_finish_runtime_suspend(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; - /* - * There are systems (for example, Intel mobile chips since Coffee - * Lake) where the power drawn while suspended can be significantly - * reduced by disabling PTM on PCIe root ports as this allows the - * port to enter a lower-power PM state and the SoC to reach a - * lower-power idle state as a whole. - */ - if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) - pci_suspend_ptm(dev); - __pci_enable_wake(dev, target_state, pci_dev_run_wake(dev)); error = pci_set_power_state(dev, target_state); - if (error) { + if (error) pci_enable_wake(dev, target_state, false); - pci_restore_ptm_state(dev); - } return error; } From 4c00cba122f3f3ae54aa5a3a1aec3afc7a2e6f94 Mon Sep 17 00:00:00 2001 From: Rajvi Jingar Date: Tue, 30 Aug 2022 03:49:12 -0700 Subject: [PATCH 149/401] PCI/PM: Simplify pci_pm_suspend_noirq() We always want to save the device state unless the driver has already done it. Rearrange the checking in pci_pm_suspend_noirq() to make this more clear. No functional change intended. [bhelgaas: commit log, rewrap comment] Link: https://lore.kernel.org/r/20220830104913.1620539-1-rajvi.jingar@linux.intel.com Signed-off-by: Rajvi Jingar Signed-off-by: Bjorn Helgaas Reviewed-by: Rafael J. Wysocki --- drivers/pci/pci-driver.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 5d8c37c3e15a..107d77f3c846 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -873,20 +873,15 @@ static int pci_pm_suspend_noirq(struct device *dev) } } - if (pci_dev->skip_bus_pm) { - /* - * Either the device is a bridge with a child in D0 below it, or - * the function is running for the second time in a row without - * going through full resume, which is possible only during - * suspend-to-idle in a spurious wakeup case. The device should - * be in D0 at this point, but if it is a bridge, it may be - * necessary to save its state. - */ - if (!pci_dev->state_saved) - pci_save_state(pci_dev); - } else if (!pci_dev->state_saved) { + if (!pci_dev->state_saved) { pci_save_state(pci_dev); - if (pci_power_manageable(pci_dev)) + + /* + * If the device is a bridge with a child in D0 below it, + * it needs to stay in D0, so check skip_bus_pm to avoid + * putting it into a low-power state in that case. + */ + if (!pci_dev->skip_bus_pm && pci_power_manageable(pci_dev)) pci_prepare_to_sleep(pci_dev); } From c7b58576370147833999fd4cc874d0f918bdf9ca Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 19 Aug 2022 15:52:02 -0700 Subject: [PATCH 150/401] f2fs: flush pending checkpoints when freezing super This avoids -EINVAL when trying to freeze f2fs. Cc: stable@vger.kernel.org Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 24 ++++++++++++++++++------ fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 5 ++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 7de48e791920..7bf1feb5ac78 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1893,15 +1893,27 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi) void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi) { struct ckpt_req_control *cprc = &sbi->cprc_info; + struct task_struct *ckpt_task; - if (cprc->f2fs_issue_ckpt) { - struct task_struct *ckpt_task = cprc->f2fs_issue_ckpt; + if (!cprc->f2fs_issue_ckpt) + return; - cprc->f2fs_issue_ckpt = NULL; - kthread_stop(ckpt_task); + ckpt_task = cprc->f2fs_issue_ckpt; + cprc->f2fs_issue_ckpt = NULL; + kthread_stop(ckpt_task); - flush_remained_ckpt_reqs(sbi, NULL); - } + f2fs_flush_ckpt_thread(sbi); +} + +void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi) +{ + struct ckpt_req_control *cprc = &sbi->cprc_info; + + flush_remained_ckpt_reqs(sbi, NULL); + + /* Let's wait for the previous dispatched checkpoint. */ + while (atomic_read(&cprc->queued_ckpt)) + io_schedule_timeout(DEFAULT_IO_TIMEOUT); } void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 6770210aae70..088c3d1574b8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3711,6 +3711,7 @@ static inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi) * checkpoint.c */ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io); +void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi); struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index); struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index); struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index e910f0e39d76..4f2ff50b247c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1671,9 +1671,8 @@ static int f2fs_freeze(struct super_block *sb) if (is_sbi_flag_set(F2FS_SB(sb), SBI_IS_DIRTY)) return -EINVAL; - /* ensure no checkpoint required */ - if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list)) - return -EINVAL; + /* Let's flush checkpoints and stop the thread. */ + f2fs_flush_ckpt_thread(F2FS_SB(sb)); /* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */ set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING); From 4f99484d27961cb194cebcd917176fa038a5025f Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 18 Aug 2022 22:40:09 -0700 Subject: [PATCH 151/401] f2fs: complete checkpoints during remount Otherwise, pending checkpoints can contribute a race condition to give a quota warning. - Thread - checkpoint thread add checkpoints to the list do_remount() down_write(&sb->s_umount); f2fs_remount() block_operations() down_read_trylock(&sb->s_umount) = 0 up_write(&sb->s_umount); f2fs_quota_sync() dquot_writeback_dquots() WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount)); Or, do_remount() down_write(&sb->s_umount); f2fs_remount() create a ckpt thread f2fs_enable_checkpoint() adds checkpoints wait for f2fs_sync_fs() trigger another pending checkpoint block_operations() down_read_trylock(&sb->s_umount) = 0 up_write(&sb->s_umount); f2fs_quota_sync() dquot_writeback_dquots() WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount)); Cc: stable@vger.kernel.org Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 4f2ff50b247c..0f29c759a898 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2185,6 +2185,9 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) f2fs_up_write(&sbi->gc_lock); f2fs_sync_fs(sbi->sb, 1); + + /* Let's ensure there's no pending checkpoint anymore */ + f2fs_flush_ckpt_thread(sbi); } static int f2fs_remount(struct super_block *sb, int *flags, char *data) @@ -2350,6 +2353,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) f2fs_stop_ckpt_thread(sbi); need_restart_ckpt = true; } else { + /* Flush if the prevous checkpoint, if exists. */ + f2fs_flush_ckpt_thread(sbi); + err = f2fs_start_ckpt_thread(sbi); if (err) { f2fs_err(sbi, From da35fe96d12d15779f3cb74929b7ed03941cf983 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 23 Aug 2022 10:18:42 -0700 Subject: [PATCH 152/401] f2fs: increase the limit for reserve_root This patch increases the threshold that limits the reserved root space from 0.2% to 12.5% by using simple shift operation. Typically Android sets 128MB, but if the storage capacity is 32GB, 0.2% which is around 64MB becomes too small. Let's relax it. Cc: stable@vger.kernel.org Reported-by: Aran Dalton Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 0f29c759a898..b8e5fe244596 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -301,10 +301,10 @@ static void f2fs_destroy_casefold_cache(void) { } static inline void limit_reserve_root(struct f2fs_sb_info *sbi) { - block_t limit = min((sbi->user_block_count << 1) / 1000, + block_t limit = min((sbi->user_block_count >> 3), sbi->user_block_count - sbi->reserved_blocks); - /* limit is 0.2% */ + /* limit is 12.5% */ if (test_opt(sbi, RESERVE_ROOT) && F2FS_OPTION(sbi).root_reserved_blocks > limit) { F2FS_OPTION(sbi).root_reserved_blocks = limit; From ddd3b16c8cc54ce776bf117bde0c4d588706ea49 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Mon, 29 Aug 2022 21:31:20 +0800 Subject: [PATCH 153/401] f2fs: replace logical value "true" with a int number The "true" is not match the parametera type "int", and we modify it. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index a5054725d0b6..460048f3c850 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -481,7 +481,7 @@ do_sync: mutex_unlock(&sbi->flush_lock); } - f2fs_sync_fs(sbi->sb, true); + f2fs_sync_fs(sbi->sb, 1); stat_inc_bg_cp_count(sbi->stat_info); } From 8140654e781de334601b260b493ff13e14379ff8 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Tue, 23 Aug 2022 19:20:22 +0800 Subject: [PATCH 154/401] f2fs: simplify code in f2fs_prepare_decomp_mem It could return directly after init_decompress_ctx. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/compress.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 70e97075e535..730256732a9e 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1568,12 +1568,8 @@ static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, if (!dic->cbuf) return -ENOMEM; - if (cops->init_decompress_ctx) { - int ret = cops->init_decompress_ctx(dic); - - if (ret) - return ret; - } + if (cops->init_decompress_ctx) + return cops->init_decompress_ctx(dic); return 0; } From cd01569b040e3f496b74e4b78c2e79fc10979b28 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Tue, 13 Sep 2022 09:48:11 -0700 Subject: [PATCH 155/401] Input: mtk-pmic-keys - add support for MT6331 PMIC keys Add support for PMIC Keys of the MT6331 PMIC. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20220913123941.385349-1-angelogioacchino.delregno@collabora.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mtk-pmic-keys.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c index 6404081253ea..9b34da0ec260 100644 --- a/drivers/input/keyboard/mtk-pmic-keys.c +++ b/drivers/input/keyboard/mtk-pmic-keys.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,10 @@ #define MTK_PMIC_PWRKEY_RST BIT(6) #define MTK_PMIC_HOMEKEY_RST BIT(5) +#define MTK_PMIC_MT6331_RST_DU_MASK GENMASK(13, 12) +#define MTK_PMIC_MT6331_PWRKEY_RST BIT(9) +#define MTK_PMIC_MT6331_HOMEKEY_RST BIT(8) + #define MTK_PMIC_PWRKEY_INDEX 0 #define MTK_PMIC_HOMEKEY_INDEX 1 #define MTK_PMIC_MAX_KEY_COUNT 2 @@ -72,6 +77,19 @@ static const struct mtk_pmic_regs mt6323_regs = { .rst_lprst_mask = MTK_PMIC_RST_DU_MASK, }; +static const struct mtk_pmic_regs mt6331_regs = { + .keys_regs[MTK_PMIC_PWRKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6331_TOPSTATUS, 0x2, + MT6331_INT_MISC_CON, 0x4, + MTK_PMIC_MT6331_PWRKEY_RST), + .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6331_TOPSTATUS, 0x4, + MT6331_INT_MISC_CON, 0x2, + MTK_PMIC_MT6331_HOMEKEY_RST), + .pmic_rst_reg = MT6331_TOP_RST_MISC, + .rst_lprst_mask = MTK_PMIC_MT6331_RST_DU_MASK, +}; + static const struct mtk_pmic_regs mt6358_regs = { .keys_regs[MTK_PMIC_PWRKEY_INDEX] = MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS, @@ -255,6 +273,9 @@ static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = { }, { .compatible = "mediatek,mt6323-keys", .data = &mt6323_regs, + }, { + .compatible = "mediatek,mt6331-keys", + .data = &mt6331_regs, }, { .compatible = "mediatek,mt6358-keys", .data = &mt6358_regs, From 10e629d31aacb2348a1e9110c31a29e98b31ce38 Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Thu, 8 Sep 2022 14:22:46 -0700 Subject: [PATCH 156/401] Input: iqs7222 - trim force communication command According to the datasheets, writing only 0xFF is sufficient to elicit a communication window. Remove the superfluous 0x00 from the force communication command. Fixes: e505edaedcb9 ("Input: add support for Azoteq IQS7222A/B/C") Signed-off-by: Jeff LaBundy Link: https://lore.kernel.org/r/20220908131548.48120-6-jeff@labundy.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/iqs7222.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index b2e8097a2e6d..376ba3e29eb6 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -1077,7 +1077,7 @@ static int iqs7222_hard_reset(struct iqs7222_private *iqs7222) static int iqs7222_force_comms(struct iqs7222_private *iqs7222) { - u8 msg_buf[] = { 0xFF, 0x00, }; + u8 msg_buf[] = { 0xFF, }; int ret; /* From 514c13b1faed74e9bc19061b6d7c78d53a3402ba Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Thu, 8 Sep 2022 14:24:24 -0700 Subject: [PATCH 157/401] Input: iqs7222 - avoid sending empty SYN_REPORT events Add a check to prevent sending undefined events, which ultimately map to SYN_REPORT. Fixes: e505edaedcb9 ("Input: add support for Azoteq IQS7222A/B/C") Signed-off-by: Jeff LaBundy Link: https://lore.kernel.org/r/20220908131548.48120-7-jeff@labundy.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/iqs7222.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index 376ba3e29eb6..b8749c3f94b4 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -2326,6 +2326,9 @@ static int iqs7222_report(struct iqs7222_private *iqs7222) int k = 2 + j * (num_chan > 16 ? 2 : 1); u16 state = le16_to_cpu(status[k + i / 16]); + if (!iqs7222->kp_type[i][j]) + continue; + input_event(iqs7222->keypad, iqs7222->kp_type[i][j], iqs7222->kp_code[i][j], From d56111ed58482de0045e1e1201122e6e71516945 Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Thu, 8 Sep 2022 14:24:35 -0700 Subject: [PATCH 158/401] Input: iqs7222 - set all ULP entry masks by default Some devices expose an ultra-low-power (ULP) mode entry mask for each channel. If the mask is set, the device cannot enter ULP so long as the corresponding channel remains in an active state. The vendor has advised setting the mask for any disabled channel. To accommodate this suggestion, initially set all masks and then clear them only if specified in the device tree. Fixes: e505edaedcb9 ("Input: add support for Azoteq IQS7222A/B/C") Signed-off-by: Jeff LaBundy Link: https://lore.kernel.org/r/20220908131548.48120-8-jeff@labundy.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/iqs7222.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index b8749c3f94b4..ddb863bf63ee 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -1771,11 +1771,9 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) if (!chan_node) return 0; - if (dev_desc->allow_offset) { - sys_setup[dev_desc->allow_offset] |= BIT(chan_index); - if (fwnode_property_present(chan_node, "azoteq,ulp-allow")) - sys_setup[dev_desc->allow_offset] &= ~BIT(chan_index); - } + if (dev_desc->allow_offset && + fwnode_property_present(chan_node, "azoteq,ulp-allow")) + sys_setup[dev_desc->allow_offset] &= ~BIT(chan_index); chan_setup[0] |= IQS7222_CHAN_SETUP_0_CHAN_EN; @@ -2206,6 +2204,9 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222) u16 *sys_setup = iqs7222->sys_setup; int error, i; + if (dev_desc->allow_offset) + sys_setup[dev_desc->allow_offset] = U16_MAX; + if (dev_desc->event_offset) sys_setup[dev_desc->event_offset] = IQS7222_EVENT_MASK_ATI; From a21599cf1213ca0bdb002adeb4fa5eade71d106e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:07 +0200 Subject: [PATCH 159/401] dt-bindings: pinctrl: qcom,sm6115-pinctrl: fix matching pin config Matching PMIC GPIOs config nodes within a '-state' node by '.*' pattern does not work as expected because of linux,phandle in the DTB: 'pins' is a required property 'function' is a required property 'rx', 'tx' do not match any of the regexes: 'pinctrl-[0-9]+' [[59]] is not of type 'object' Make the schema stricter and expect such nodes to be followed with a '-pins' suffix. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Iskren Chernev Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-2-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6115-pinctrl.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml index d8443811767d..8a2b4767c7b6 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml @@ -59,8 +59,9 @@ patternProperties: oneOf: - $ref: "#/$defs/qcom-sm6115-tlmm-state" - patternProperties: - ".*": + "-pins$": $ref: "#/$defs/qcom-sm6115-tlmm-state" + additionalProperties: false '$defs': qcom-sm6115-tlmm-state: @@ -155,25 +156,25 @@ examples: gpio-ranges = <&tlmm 0 0 114>; sdc2_on_state: sdc2-on-state { - clk { + clk-pins { pins = "sdc2_clk"; bias-disable; drive-strength = <16>; }; - cmd { + cmd-pins { pins = "sdc2_cmd"; bias-pull-up; drive-strength = <10>; }; - data { + data-pins { pins = "sdc2_data"; bias-pull-up; drive-strength = <10>; }; - sd-cd { + sd-cd-pins { pins = "gpio88"; function = "gpio"; bias-pull-up; From b17cf20dfc188f48f2746e1178cfde910cfa3be2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:08 +0200 Subject: [PATCH 160/401] dt-bindings: pinctrl: qcom,sm6115-pinctrl: require function on GPIOs Require function on GPIOs (so not on SD card pins). Signed-off-by: Krzysztof Kozlowski Reviewed-by: Iskren Chernev Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-3-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6115-pinctrl.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml index 8a2b4767c7b6..28b29bf714b4 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml @@ -69,7 +69,6 @@ patternProperties: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" properties: pins: @@ -121,6 +120,16 @@ patternProperties: required: - pins + allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|10[0-9]|11[0-2])$" + then: + required: + - function + additionalProperties: false allOf: From 495ffc067c6719f3a1722632455eb6fea9914f70 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:09 +0200 Subject: [PATCH 161/401] dt-bindings: pinctrl: qcom,sm6115-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Iskren Chernev Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-4-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6115-pinctrl.yaml | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml index 28b29bf714b4..e39fbb36d8c1 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml @@ -150,44 +150,44 @@ additionalProperties: false examples: - | - #include - tlmm: pinctrl@500000 { - compatible = "qcom,sm6115-tlmm"; - reg = <0x500000 0x400000>, - <0x900000 0x400000>, - <0xd00000 0x400000>; - reg-names = "west", "south", "east"; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 114>; + #include + tlmm: pinctrl@500000 { + compatible = "qcom,sm6115-tlmm"; + reg = <0x500000 0x400000>, + <0x900000 0x400000>, + <0xd00000 0x400000>; + reg-names = "west", "south", "east"; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 114>; - sdc2_on_state: sdc2-on-state { - clk-pins { - pins = "sdc2_clk"; - bias-disable; - drive-strength = <16>; - }; + sdc2_on_state: sdc2-on-state { + clk-pins { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <16>; + }; - cmd-pins { - pins = "sdc2_cmd"; - bias-pull-up; - drive-strength = <10>; - }; + cmd-pins { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <10>; + }; - data-pins { - pins = "sdc2_data"; - bias-pull-up; - drive-strength = <10>; - }; + data-pins { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <10>; + }; - sd-cd-pins { - pins = "gpio88"; - function = "gpio"; - bias-pull-up; - drive-strength = <2>; - }; - }; + sd-cd-pins { + pins = "gpio88"; + function = "gpio"; + bias-pull-up; + drive-strength = <2>; + }; }; + }; From 5d66124f619dafc1ca2c5b7b90b3fa355d995fa0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:10 +0200 Subject: [PATCH 162/401] dt-bindings: pinctrl: qcom,sm6125-pinctrl: fix matching pin config Matching PMIC GPIOs config nodes within a '-state' node by '.*' pattern does not work as expected because of linux,phandle in the DTB: 'pins' is a required property 'function' is a required property 'rx', 'tx' do not match any of the regexes: 'pinctrl-[0-9]+' [[59]] is not of type 'object' Make the schema stricter and expect such nodes to be followed with a '-pins' suffix. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-5-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml index c8eec845ade9..84ed16f9915d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml @@ -51,8 +51,9 @@ patternProperties: oneOf: - $ref: "#/$defs/qcom-sm6125-tlmm-state" - patternProperties: - ".*": + "-pins$": $ref: "#/$defs/qcom-sm6125-tlmm-state" + additionalProperties: false $defs: qcom-sm6125-tlmm-state: From d1fc02d47bc4ba291ea85b85031cfa548da65724 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:11 +0200 Subject: [PATCH 163/401] dt-bindings: pinctrl: qcom,sm6125-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-6-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6125-pinctrl.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml index 84ed16f9915d..735eb5d6834d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml @@ -61,7 +61,6 @@ $defs: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" properties: pins: @@ -112,7 +111,16 @@ $defs: required: - pins - - function + + allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + - if: + properties: + pins: + pattern: "^gpio[0-9]|[1-9][0-9]|1[0-2][0-9]|13[0-2]$" + then: + required: + - function additionalProperties: false From 15239930127566a21294df41f9b73ddb5e4011f6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:12 +0200 Subject: [PATCH 164/401] dt-bindings: pinctrl: qcom,sm6125-pinctrl: extend example Extend example with children for pin configuration and indent it with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-7-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6125-pinctrl.yaml | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml index 735eb5d6834d..5cb8b272cb7d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6125-pinctrl.yaml @@ -126,17 +126,37 @@ $defs: examples: - | - #include - pinctrl@500000 { - compatible = "qcom,sm6125-tlmm"; - reg = <0x00500000 0x400000>, - <0x00900000 0x400000>, - <0x00d00000 0x400000>; - reg-names = "west", "south", "east"; - interrupts = ; - gpio-controller; - gpio-ranges = <&tlmm 0 0 134>; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; + #include + pinctrl@500000 { + compatible = "qcom,sm6125-tlmm"; + reg = <0x00500000 0x400000>, + <0x00900000 0x400000>, + <0x00d00000 0x400000>; + reg-names = "west", "south", "east"; + interrupts = ; + gpio-controller; + gpio-ranges = <&tlmm 0 0 134>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + + sdc2-off-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <2>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <2>; + bias-pull-up; + }; }; + }; From 7c291167877809723f990b989a05367565672586 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:13 +0200 Subject: [PATCH 165/401] dt-bindings: pinctrl: qcom,sm6350-pinctrl: fix matching pin config Matching PMIC GPIOs config nodes within a '-state' node by '.*' pattern does not work as expected because of linux,phandle in the DTB: 'pins' is a required property 'function' is a required property 'rx', 'tx' do not match any of the regexes: 'pinctrl-[0-9]+' [[59]] is not of type 'object' Make the schema stricter and expect such nodes to be followed with a '-pins' suffix. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-8-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml index 898608671c4b..85a4ff5a5625 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml @@ -44,8 +44,9 @@ patternProperties: oneOf: - $ref: "#/$defs/qcom-sm6350-tlmm-state" - patternProperties: - ".*": + "-pins$": $ref: "#/$defs/qcom-sm6350-tlmm-state" + additionalProperties: false $defs: qcom-sm6350-tlmm-state: @@ -133,13 +134,13 @@ examples: }; uart-w-subnodes-state { - rx { + rx-pins { pins = "gpio25"; function = "qup13_f2"; bias-disable; }; - tx { + tx-pins { pins = "gpio26"; function = "qup13_f2"; bias-disable; From 5f3332e9450d2c48c2cfc9d70e96693a890af373 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:14 +0200 Subject: [PATCH 166/401] dt-bindings: pinctrl: qcom,sm6350-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-9-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6350-pinctrl.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml index 85a4ff5a5625..0c4bf6e90ba0 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml @@ -54,7 +54,6 @@ $defs: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" properties: pins: @@ -111,7 +110,16 @@ $defs: required: - pins - - function + + allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|1[0-4][0-9]|15[0-7])$" + then: + required: + - function additionalProperties: false From dc246ef73f5990b839d30b00d01066d95293aa85 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:15 +0200 Subject: [PATCH 167/401] dt-bindings: pinctrl: qcom,sm6350-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-10-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6350-pinctrl.yaml | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml index 0c4bf6e90ba0..856b9c567ecb 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-pinctrl.yaml @@ -125,34 +125,34 @@ $defs: examples: - | - #include - pinctrl@f100000 { - compatible = "qcom,sm6350-tlmm"; - reg = <0x0f100000 0x300000>; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 157>; + #include + pinctrl@f100000 { + compatible = "qcom,sm6350-tlmm"; + reg = <0x0f100000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 157>; - gpio-wo-subnode-state { - pins = "gpio1"; - function = "gpio"; - }; - - uart-w-subnodes-state { - rx-pins { - pins = "gpio25"; - function = "qup13_f2"; - bias-disable; - }; - - tx-pins { - pins = "gpio26"; - function = "qup13_f2"; - bias-disable; - }; - }; + gpio-wo-subnode-state { + pins = "gpio1"; + function = "gpio"; }; + + uart-w-subnodes-state { + rx-pins { + pins = "gpio25"; + function = "qup13_f2"; + bias-disable; + }; + + tx-pins { + pins = "gpio26"; + function = "qup13_f2"; + bias-disable; + }; + }; + }; ... From 51af3784f15facb4a011d59721a54a8b4ae2a3ed Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:16 +0200 Subject: [PATCH 168/401] dt-bindings: pinctrl: qcom,sm6375-pinctrl: fix matching pin config Matching PMIC GPIOs config nodes within a '-state' node by '.*' pattern does not work as expected because of linux,phandle in the DTB: 'pins' is a required property 'function' is a required property 'rx', 'tx' do not match any of the regexes: 'pinctrl-[0-9]+' [[59]] is not of type 'object' Make the schema stricter and expect such nodes to be followed with a '-pins' suffix. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-11-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml index 3908807a8339..50f0ca5ab7e7 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml @@ -44,8 +44,9 @@ patternProperties: oneOf: - $ref: "#/$defs/qcom-sm6375-tlmm-state" - patternProperties: - ".*": + "-pins$": $ref: "#/$defs/qcom-sm6375-tlmm-state" + additionalProperties: false $defs: qcom-sm6375-tlmm-state: @@ -142,13 +143,13 @@ examples: }; uart-w-subnodes-state { - rx { + rx-pins { pins = "gpio18"; function = "qup13_f2"; bias-pull-up; }; - tx { + tx-pins { pins = "gpio19"; function = "qup13_f2"; bias-disable; From c8441085e2c0e17ef0610ba4ba2da100677ddf41 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:17 +0200 Subject: [PATCH 169/401] dt-bindings: pinctrl: qcom,sm6375-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-12-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6375-tlmm.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml index 50f0ca5ab7e7..dbd91d6b63b3 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml @@ -54,7 +54,6 @@ $defs: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" properties: pins: @@ -120,7 +119,16 @@ $defs: required: - pins - - function + + allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|1[0-4][0-9]|15[0-6])$" + then: + required: + - function additionalProperties: false From e3c2e3840742800131a9530d07e30a809d36dd65 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:18 +0200 Subject: [PATCH 170/401] dt-bindings: pinctrl: qcom,sm6375-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-13-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6375-tlmm.yaml | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml index dbd91d6b63b3..025faf87d147 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6375-tlmm.yaml @@ -134,34 +134,34 @@ $defs: examples: - | - #include - pinctrl@500000 { - compatible = "qcom,sm6375-tlmm"; - reg = <0x00500000 0x800000>; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 157>; + #include + pinctrl@500000 { + compatible = "qcom,sm6375-tlmm"; + reg = <0x00500000 0x800000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 157>; - gpio-wo-subnode-state { - pins = "gpio1"; - function = "gpio"; - }; - - uart-w-subnodes-state { - rx-pins { - pins = "gpio18"; - function = "qup13_f2"; - bias-pull-up; - }; - - tx-pins { - pins = "gpio19"; - function = "qup13_f2"; - bias-disable; - }; - }; + gpio-wo-subnode-state { + pins = "gpio1"; + function = "gpio"; }; + + uart-w-subnodes-state { + rx-pins { + pins = "gpio18"; + function = "qup13_f2"; + bias-pull-up; + }; + + tx-pins { + pins = "gpio19"; + function = "qup13_f2"; + bias-disable; + }; + }; + }; ... From 6e6e1ef6b59d70c289f899d46049ab54bcf3f9c4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:19 +0200 Subject: [PATCH 171/401] dt-bindings: pinctrl: qcom,sm8250-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-14-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm8250-pinctrl.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml index 15bb1018cf21..12bdc2e67c4d 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml @@ -110,7 +110,15 @@ patternProperties: required: - pins - - function + + allOf: + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|1[0-7][0-9])$" + then: + required: + - function additionalProperties: false From 2723c2530c20406425e6e44a29b9e36443e07e42 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:20 +0200 Subject: [PATCH 172/401] dt-bindings: pinctrl: qcom,sm8250-pinctrl: reference tlmm common pins Each subnode configuring pins (so the final -pins or pinconf) should reference common TLMM pin definition. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-15-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml index 12bdc2e67c4d..bccc83f22aae 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml @@ -112,6 +112,7 @@ patternProperties: - pins allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" - if: properties: pins: From d70f858f82374021f1d5379a49cb74022a216120 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:21 +0200 Subject: [PATCH 173/401] dt-bindings: pinctrl: qcom,sm8250-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-16-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm8250-pinctrl.yaml | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml index bccc83f22aae..c44d02d28bc9 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml @@ -141,18 +141,18 @@ additionalProperties: false examples: - | - #include - pinctrl@1f00000 { - compatible = "qcom,sm8250-pinctrl"; - reg = <0x0f100000 0x300000>, - <0x0f500000 0x300000>, - <0x0f900000 0x300000>; - reg-names = "west", "south", "north"; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 180>; - wakeup-parent = <&pdc>; - }; + #include + pinctrl@1f00000 { + compatible = "qcom,sm8250-pinctrl"; + reg = <0x0f100000 0x300000>, + <0x0f500000 0x300000>, + <0x0f900000 0x300000>; + reg-names = "west", "south", "north"; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 180>; + wakeup-parent = <&pdc>; + }; From e9668427de337c67b1e18e9e1979180514631440 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:22 +0200 Subject: [PATCH 174/401] dt-bindings: pinctrl: qcom,sm8350-pinctrl: fix matching pin config Matching PMIC GPIOs config nodes within a '-state' node by '.*' pattern does not work as expected because of linux,phandle in the DTB: sm8350-hdk.dtb: pinctrl@f100000: qup-uart3-default-state: 'oneOf' conditional failed, one must be fixed: 'pins' is a required property 'function' is a required property 'rx', 'tx' do not match any of the regexes: 'pinctrl-[0-9]+' [[59]] is not of type 'object' Make the schema stricter and expect such nodes to be followed with a '-pins' suffix. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-17-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml index 6b7789db2f75..211cca11f94f 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml @@ -44,8 +44,9 @@ patternProperties: oneOf: - $ref: "#/$defs/qcom-sm8350-tlmm-state" - patternProperties: - ".*": + "-pins$": $ref: "#/$defs/qcom-sm8350-tlmm-state" + additionalProperties: false $defs: qcom-sm8350-tlmm-state: @@ -130,13 +131,13 @@ examples: }; uart-w-subnodes-state { - rx { + rx-pins { pins = "gpio18"; function = "qup3"; bias-pull-up; }; - tx { + tx-pins { pins = "gpio19"; function = "qup3"; bias-disable; From 2d4e77a71f031928b95c8ab97b8ace0e46c6cc5f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:23 +0200 Subject: [PATCH 175/401] dt-bindings: pinctrl: qcom,sm8350-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-18-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm8350-pinctrl.yaml | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml index 211cca11f94f..f3106d25adcf 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml @@ -114,34 +114,34 @@ $defs: examples: - | - #include - pinctrl@f100000 { - compatible = "qcom,sm8350-tlmm"; - reg = <0x0f100000 0x300000>; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 203>; + #include + pinctrl@f100000 { + compatible = "qcom,sm8350-tlmm"; + reg = <0x0f100000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 203>; - gpio-wo-subnode-state { - pins = "gpio1"; - function = "gpio"; - }; - - uart-w-subnodes-state { - rx-pins { - pins = "gpio18"; - function = "qup3"; - bias-pull-up; - }; - - tx-pins { - pins = "gpio19"; - function = "qup3"; - bias-disable; - }; - }; + gpio-wo-subnode-state { + pins = "gpio1"; + function = "gpio"; }; + + uart-w-subnodes-state { + rx-pins { + pins = "gpio18"; + function = "qup3"; + bias-pull-up; + }; + + tx-pins { + pins = "gpio19"; + function = "qup3"; + bias-disable; + }; + }; + }; ... From 34b88934e60e182d78b4e5f22ea8f702dff49f55 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:24 +0200 Subject: [PATCH 176/401] dt-bindings: pinctrl: qcom,sm8350-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-19-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm8350-pinctrl.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml index f3106d25adcf..6ae5571f60da 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8350-pinctrl.yaml @@ -54,7 +54,6 @@ $defs: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" properties: pins: @@ -108,7 +107,16 @@ $defs: required: - pins - - function + + allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|20[0-3])$" + then: + required: + - function additionalProperties: false From d4ac2a2b7c6265156b2df6b4841e7f1117638d2b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:25 +0200 Subject: [PATCH 177/401] dt-bindings: pinctrl: qcom,sm8450-pinctrl: fix matching pin config Matching PMIC GPIOs config nodes within a '-state' node by '.*' pattern does not work as expected because of linux,phandle in the DTB: qcom/sm4250-oneplus-billie2.dtb: pinctrl@500000: sdc1-on-state: 'oneOf' conditional failed, one must be fixed: 'pins' is a required property 'clk', 'cmd', 'data', 'rclk' do not match any of the regexes: 'pinctrl-[0-9]+' [[26]] is not of type 'object' Make the schema stricter and expect such nodes to be followed with a '-pins' suffix. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-20-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml index 9c891246245b..d1d1c1455b3c 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml @@ -43,8 +43,9 @@ patternProperties: oneOf: - $ref: "#/$defs/qcom-sm8450-tlmm-state" - patternProperties: - ".*": + "-pins$": $ref: "#/$defs/qcom-sm8450-tlmm-state" + additionalProperties: false $defs: qcom-sm8450-tlmm-state: @@ -127,13 +128,13 @@ examples: }; uart-w-subnodes-state { - rx { + rx-pins { pins = "gpio26"; function = "qup7"; bias-pull-up; }; - tx { + tx-pins { pins = "gpio27"; function = "qup7"; bias-disable; From fde270ebb7eddf5aeae3e6235afdc92390d4d8f0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:26 +0200 Subject: [PATCH 178/401] dt-bindings: pinctrl: qcom,sm8450-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-21-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm8450-pinctrl.yaml | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml index d1d1c1455b3c..87347e9c5f1c 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml @@ -111,34 +111,34 @@ $defs: examples: - | - #include - pinctrl@f100000 { - compatible = "qcom,sm8450-tlmm"; - reg = <0x0f100000 0x300000>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&tlmm 0 0 211>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = ; + #include + pinctrl@f100000 { + compatible = "qcom,sm8450-tlmm"; + reg = <0x0f100000 0x300000>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&tlmm 0 0 211>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = ; - gpio-wo-subnode-state { - pins = "gpio1"; - function = "gpio"; - }; - - uart-w-subnodes-state { - rx-pins { - pins = "gpio26"; - function = "qup7"; - bias-pull-up; - }; - - tx-pins { - pins = "gpio27"; - function = "qup7"; - bias-disable; - }; - }; + gpio-wo-state { + pins = "gpio1"; + function = "gpio"; }; + + uart-w-state { + rx-pins { + pins = "gpio26"; + function = "qup7"; + bias-pull-up; + }; + + tx-pins { + pins = "gpio27"; + function = "qup7"; + bias-disable; + }; + }; + }; ... From 3cf5e17b26593db8a0293704614dd30d938b9a04 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:27 +0200 Subject: [PATCH 179/401] dt-bindings: pinctrl: qcom,sm8450-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-22-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm8450-pinctrl.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml index 87347e9c5f1c..296f503c1d97 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml @@ -53,7 +53,6 @@ $defs: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" properties: pins: @@ -105,7 +104,16 @@ $defs: required: - pins - - function + + allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|20[0-9])$" + then: + required: + - function additionalProperties: false From 9779ed30f92c47604e40dcd8f20615712f63cbca Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:28 +0200 Subject: [PATCH 180/401] dt-bindings: pinctrl: qcom,sm8450-pinctrl: add gpio-line-names Add common gpio-line-names property and restrict gpio-reserved-ranges to fixed size. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-23-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml index 296f503c1d97..9cd97a467648 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-pinctrl.yaml @@ -27,7 +27,14 @@ properties: interrupt-controller: true '#interrupt-cells': true gpio-controller: true - gpio-reserved-ranges: true + + gpio-reserved-ranges: + minItems: 1 + maxItems: 105 + + gpio-line-names: + maxItems: 209 + '#gpio-cells': true gpio-ranges: true wakeup-parent: true From b76881c1288eca49c1579ed5f2bf8e6bedf25a2b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:29 +0200 Subject: [PATCH 181/401] dt-bindings: pinctrl: qcom,sc7280-pinctrl: correct number of GPIOs There are 182 GPIOs on SC7280. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-24-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml index 2d228164357c..f948a7f30f6a 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml @@ -60,7 +60,7 @@ patternProperties: subnode. items: oneOf: - - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-7][0-4])$" + - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-7][0-9]|18[0-2])$" - enum: [ sdc1_rclk, sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data, ufs_reset ] minItems: 1 From c35edcef53f8ca7a07bc4bbe95f756e55a74feb0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:30 +0200 Subject: [PATCH 182/401] dt-bindings: pinctrl: qcom,sc7280-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-25-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sc7280-pinctrl.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml index f948a7f30f6a..9bd5fbdde9a2 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml @@ -51,7 +51,6 @@ patternProperties: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "/schemas/pinctrl/pincfg-node.yaml" properties: pins: @@ -118,7 +117,16 @@ patternProperties: required: - pins - - function + + allOf: + - $ref: /schemas/pinctrl/pincfg-node.yaml + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|1[0-7][0-9]|18[0-2])$" + then: + required: + - function additionalProperties: false From 2f23ae0f24f7ced01195d263a1db731a754b6f00 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:31 +0200 Subject: [PATCH 183/401] dt-bindings: pinctrl: qcom,sc7280-pinctrl: add gpio-line-names Add common gpio-line-names property (used on SC7280 Herobrine boards). Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-26-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml index 9bd5fbdde9a2..35d3962dac58 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml @@ -42,6 +42,9 @@ properties: gpio-ranges: maxItems: 1 + gpio-line-names: + maxItems: 174 + wakeup-parent: true #PIN CONFIGURATION NODES From 94a0cf14d7d52cb5889a6058bb98d541209effd1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:32 +0200 Subject: [PATCH 184/401] dt-bindings: pinctrl: qcom,sc7280-pinctrl: reference tlmm schema Qualcomm TLMM pin controller bindings should reference generic TLMM schema (which also pulls generic pinctrl schema). Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-27-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml index 35d3962dac58..b29fac302e6e 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml @@ -134,7 +134,7 @@ patternProperties: additionalProperties: false allOf: - - $ref: "pinctrl.yaml#" + - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml# required: - compatible From 44208c8238ea49c1ff827780a08c142a82517190 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:33 +0200 Subject: [PATCH 185/401] dt-bindings: pinctrl: qcom,sc7280-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-28-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sc7280-pinctrl.yaml | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml index b29fac302e6e..30e682579391 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-pinctrl.yaml @@ -150,22 +150,22 @@ additionalProperties: false examples: - | - #include - tlmm: pinctrl@f000000 { - compatible = "qcom,sc7280-pinctrl"; - reg = <0xf000000 0x1000000>; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 175>; - wakeup-parent = <&pdc>; + #include + tlmm: pinctrl@f000000 { + compatible = "qcom,sc7280-pinctrl"; + reg = <0xf000000 0x1000000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 175>; + wakeup-parent = <&pdc>; - qup_uart5_default: qup-uart5-pins { - pins = "gpio46", "gpio47"; - function = "qup13"; - drive-strength = <2>; - bias-disable; - }; + qup_uart5_default: qup-uart5-pins { + pins = "gpio46", "gpio47"; + function = "qup13"; + drive-strength = <2>; + bias-disable; }; + }; From 985ea2c8d8bc33eca2ba8455f64e83148c3693e8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:34 +0200 Subject: [PATCH 186/401] dt-bindings: pinctrl: qcom,sc8180x-pinctrl: fix matching pin config Matching PMIC GPIOs config nodes within a '-state' node by '.*' pattern does not work as expected because of linux,phandle in the DTB: 'pins' is a required property 'function' is a required property 'rx', 'tx' do not match any of the regexes: 'pinctrl-[0-9]+' [[59]] is not of type 'object' Make the schema stricter and expect such nodes to be followed with a '-pins' suffix. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-29-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml index 86509172603d..646fabdf81f7 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml @@ -51,8 +51,9 @@ patternProperties: oneOf: - $ref: "#/$defs/qcom-sc8180x-tlmm-state" - patternProperties: - ".*": + "-pins$": $ref: "#/$defs/qcom-sc8180x-tlmm-state" + additionalProperties: false '$defs': qcom-sc8180x-tlmm-state: @@ -137,13 +138,13 @@ examples: }; uart-w-subnodes-state { - rx { + rx-pins { pins = "gpio4"; function = "qup6"; bias-pull-up; }; - tx { + tx-pins { pins = "gpio5"; function = "qup6"; bias-disable; From c21692d5f81dd7153244f82c1bd127603e59c24d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:35 +0200 Subject: [PATCH 187/401] dt-bindings: pinctrl: qcom,sc8180x-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-30-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sc8180x-pinctrl.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml index 646fabdf81f7..4afe20bac87c 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml @@ -61,7 +61,6 @@ patternProperties: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" properties: pins: @@ -112,7 +111,16 @@ patternProperties: required: - pins - - function + + allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|1[0-8][0-9])$" + then: + required: + - function additionalProperties: false From 31fb6fc82f6a63df9543f247743e894ac453ac0c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:36 +0200 Subject: [PATCH 188/401] dt-bindings: pinctrl: qcom,sc8180x-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-31-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../pinctrl/qcom,sc8180x-pinctrl.yaml | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml index 4afe20bac87c..b98eeba2c530 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc8180x-pinctrl.yaml @@ -126,37 +126,37 @@ patternProperties: examples: - | - #include - pinctrl@3100000 { - compatible = "qcom,sc8180x-tlmm"; - reg = <0x03100000 0x300000>, - <0x03500000 0x700000>, - <0x03d00000 0x300000>; - reg-names = "west", "east", "south"; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 190>; + #include + pinctrl@3100000 { + compatible = "qcom,sc8180x-tlmm"; + reg = <0x03100000 0x300000>, + <0x03500000 0x700000>, + <0x03d00000 0x300000>; + reg-names = "west", "east", "south"; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 190>; - gpio-wo-subnode-state { - pins = "gpio1"; - function = "gpio"; - }; - - uart-w-subnodes-state { - rx-pins { - pins = "gpio4"; - function = "qup6"; - bias-pull-up; - }; - - tx-pins { - pins = "gpio5"; - function = "qup6"; - bias-disable; - }; - }; + gpio-wo-subnode-state { + pins = "gpio1"; + function = "gpio"; }; + + uart-w-subnodes-state { + rx-pins { + pins = "gpio4"; + function = "qup6"; + bias-pull-up; + }; + + tx-pins { + pins = "gpio5"; + function = "qup6"; + bias-disable; + }; + }; + }; ... From 22b4fb602283e6f8807225d84a7918fd2961bff5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:37 +0200 Subject: [PATCH 189/401] dt-bindings: pinctrl: qcom,sc8280xp-pinctrl: fix matching pin config Matching PMIC GPIOs config nodes within a '-state' node by '.*' pattern does not work as expected because of linux,phandle in the DTB: 'pins' is a required property 'function' is a required property 'rx', 'tx' do not match any of the regexes: 'pinctrl-[0-9]+' [[59]] is not of type 'object' Make the schema stricter and expect such nodes to be followed with a '-pins' suffix. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-32-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml index 87a381c9a19d..5147afc28721 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml @@ -43,8 +43,9 @@ patternProperties: oneOf: - $ref: "#/$defs/qcom-sc8280xp-tlmm-state" - patternProperties: - ".*": + "-pins$": $ref: "#/$defs/qcom-sc8280xp-tlmm-state" + additionalProperties: false '$defs': qcom-sc8280xp-tlmm-state: @@ -135,13 +136,13 @@ examples: }; uart-w-subnodes-state { - rx { + rx-pins { pins = "gpio4"; function = "qup14"; bias-pull-up; }; - tx { + tx-pins { pins = "gpio5"; function = "qup14"; bias-disable; From 3fb7fe5d3a3ee76416f862ea25c275357820b294 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:38 +0200 Subject: [PATCH 190/401] dt-bindings: pinctrl: qcom,sc8280xp-pinctrl: do not require function on non-GPIOs Certain pins, like SDcard related, do not have functions and such should not be required: sdc1-clk-pins: 'function' is a required property Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-33-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml index 5147afc28721..8610f2701388 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml @@ -53,7 +53,6 @@ patternProperties: description: Pinctrl node's client devices use subnodes for desired pin configuration. Client device subnodes use below standard properties. - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" properties: pins: @@ -113,7 +112,16 @@ patternProperties: required: - pins - - function + + allOf: + - $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + - if: + properties: + pins: + pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-1][0-9]|22[0-7])$" + then: + required: + - function additionalProperties: false From ee83ef13dc405f6b55ad8d931cd0df9dee3a8ae8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 12 Sep 2022 08:17:39 +0200 Subject: [PATCH 191/401] dt-bindings: pinctrl: qcom,sc8280xp-pinctrl: fix indentation in example Bindings example should be indented with 4-spaces. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220912061746.6311-34-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- .../pinctrl/qcom,sc8280xp-pinctrl.yaml | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml index 8610f2701388..b9ab130cd558 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc8280xp-pinctrl.yaml @@ -127,34 +127,34 @@ patternProperties: examples: - | - #include - pinctrl@f100000 { - compatible = "qcom,sc8280xp-tlmm"; - reg = <0x0f100000 0x300000>; - interrupts = ; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - gpio-ranges = <&tlmm 0 0 230>; + #include + pinctrl@f100000 { + compatible = "qcom,sc8280xp-tlmm"; + reg = <0x0f100000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 230>; - gpio-wo-subnode-state { - pins = "gpio1"; - function = "gpio"; - }; - - uart-w-subnodes-state { - rx-pins { - pins = "gpio4"; - function = "qup14"; - bias-pull-up; - }; - - tx-pins { - pins = "gpio5"; - function = "qup14"; - bias-disable; - }; - }; + gpio-wo-subnode-state { + pins = "gpio1"; + function = "gpio"; }; + + uart-w-subnodes-state { + rx-pins { + pins = "gpio4"; + function = "qup14"; + bias-pull-up; + }; + + tx-pins { + pins = "gpio5"; + function = "qup14"; + bias-disable; + }; + }; + }; ... From 3f668365bcd8d17b4bcd0fdb62e5c748753196ec Mon Sep 17 00:00:00 2001 From: Colin Foster Date: Fri, 9 Sep 2022 08:38:02 -0700 Subject: [PATCH 192/401] pinctrl: ocelot: add help and description information to ocelot pinctrl kconfig Add missed help information and module export name to the Microsemi Ocelot and Jaguar2 SoC. Signed-off-by: Colin Foster Link: https://lore.kernel.org/r/20220909153802.3370088-1-colin.foster@in-advantage.com Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 5 +++++ drivers/pinctrl/pinctrl-ocelot.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index c09562fbb1b7..da87f2dc358b 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -335,6 +335,11 @@ config PINCTRL_OCELOT select GENERIC_PINMUX_FUNCTIONS select OF_GPIO select REGMAP_MMIO + help + Support for the internal GPIO interfaces on Microsemi Ocelot and + Jaguar2 SoCs. + + If conpiled as a module, the module name will be pinctrl-ocelot. config PINCTRL_OXNAS bool diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c index c5fd154990c8..647e91490bac 100644 --- a/drivers/pinctrl/pinctrl-ocelot.c +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -2052,4 +2052,6 @@ static struct platform_driver ocelot_pinctrl_driver = { .probe = ocelot_pinctrl_probe, }; module_platform_driver(ocelot_pinctrl_driver); + +MODULE_DESCRIPTION("Ocelot Chip Pinctrl Driver"); MODULE_LICENSE("Dual MIT/GPL"); From 7984b43542070f5888546d95b48003c4a8af7c0f Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Wed, 14 Sep 2022 05:34:49 -0700 Subject: [PATCH 193/401] Input: synaptics - enable InterTouch for the ThinkPad P1 G3 Noticed this while trying to debug some unrelated issues: this laptop has the ability to use rmi4 but doesn't by default. So let's fix that. Tested locally, including mouse buttons, on my ThinkPad P1 G3. This might also enable the X1 Extreme G3, but I don't have such a system to test locally (presumably Mark can chime in if that's the case). Signed-off-by: Lyude Paul Link: https://lore.kernel.org/r/20220909202127.141761-1-lyude@redhat.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index e3f657713b55..4971ec9f9748 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -182,6 +182,7 @@ static const char * const smbus_pnp_ids[] = { "LEN0099", /* X1 Extreme Gen 1 / P1 Gen 1 */ "LEN009b", /* T580 */ "LEN0402", /* X1 Extreme Gen 2 / P1 Gen 2 */ + "LEN040f", /* P1 Gen 3 */ "LEN200f", /* T450s */ "LEN2044", /* L470 */ "LEN2054", /* E480 */ From 92858eb6cb64cfafdc2b35c942d1812275f4205a Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Mon, 12 Sep 2022 17:24:40 +0800 Subject: [PATCH 194/401] dt-bindings: pinctrl: update bindings for MT7986 SoC Add wifi pins in the description and set 'maxItems' for groups and pins. Reviewed-by: Sam Shih Signed-off-by: Peter Chiu Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20220912092440.21011-1-chui-hao.chiu@mediatek.com Signed-off-by: Linus Walleij --- .../pinctrl/mediatek,mt7986-pinctrl.yaml | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml index 4eadea55df10..06c819ae7d50 100644 --- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml @@ -117,6 +117,10 @@ patternProperties: "i2s" "audio" 62, 63, 64, 65 "switch_int" "eth" 66 "mdc_mdio" "eth" 67 + "wf_2g" "wifi" 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 + "wf_5g" "wifi" 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 + "wf_dbdc" "wifi" 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85 $ref: "/schemas/pinctrl/pinmux-node.yaml" properties: @@ -234,7 +238,9 @@ patternProperties: then: properties: groups: - enum: [wf_2g, wf_5g, wf_dbdc] + items: + enum: [wf_2g, wf_5g, wf_dbdc] + maxItems: 3 '.*conf.*': type: object additionalProperties: false @@ -248,25 +254,27 @@ patternProperties: An array of strings. Each string contains the name of a pin. There is no PIN 41 to PIN 65 above on mt7686b, you can only use those pins on mt7986a. - enum: [SYS_WATCHDOG, WF2G_LED, WF5G_LED, I2C_SCL, I2C_SDA, GPIO_0, - GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, GPIO_6, GPIO_7, - GPIO_8, GPIO_9, GPIO_10, GPIO_11, GPIO_12, GPIO_13, GPIO_14, - GPIO_15, PWM0, PWM1, SPI0_CLK, SPI0_MOSI, SPI0_MISO, SPI0_CS, - SPI0_HOLD, SPI0_WP, SPI1_CLK, SPI1_MOSI, SPI1_MISO, SPI1_CS, - SPI2_CLK, SPI2_MOSI, SPI2_MISO, SPI2_CS, SPI2_HOLD, SPI2_WP, - UART0_RXD, UART0_TXD, PCIE_PERESET_N, UART1_RXD, UART1_TXD, - UART1_CTS, UART1_RTS, UART2_RXD, UART2_TXD, UART2_CTS, - UART2_RTS, EMMC_DATA_0, EMMC_DATA_1, EMMC_DATA_2, - EMMC_DATA_3, EMMC_DATA_4, EMMC_DATA_5, EMMC_DATA_6, - EMMC_DATA_7, EMMC_CMD, EMMC_CK, EMMC_DSL, EMMC_RSTB, PCM_DTX, - PCM_DRX, PCM_CLK, PCM_FS, MT7531_INT, SMI_MDC, SMI_MDIO, - WF0_DIG_RESETB, WF0_CBA_RESETB, WF0_XO_REQ, WF0_TOP_CLK, - WF0_TOP_DATA, WF0_HB1, WF0_HB2, WF0_HB3, WF0_HB4, WF0_HB0, - WF0_HB0_B, WF0_HB5, WF0_HB6, WF0_HB7, WF0_HB8, WF0_HB9, - WF0_HB10, WF1_DIG_RESETB, WF1_CBA_RESETB, WF1_XO_REQ, - WF1_TOP_CLK, WF1_TOP_DATA, WF1_HB1, WF1_HB2, WF1_HB3, - WF1_HB4, WF1_HB0, WF1_HB0_B, WF1_HB5, WF1_HB6, WF1_HB7, - WF1_HB8] + items: + enum: [SYS_WATCHDOG, WF2G_LED, WF5G_LED, I2C_SCL, I2C_SDA, GPIO_0, + GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, GPIO_6, GPIO_7, + GPIO_8, GPIO_9, GPIO_10, GPIO_11, GPIO_12, GPIO_13, GPIO_14, + GPIO_15, PWM0, PWM1, SPI0_CLK, SPI0_MOSI, SPI0_MISO, SPI0_CS, + SPI0_HOLD, SPI0_WP, SPI1_CLK, SPI1_MOSI, SPI1_MISO, SPI1_CS, + SPI2_CLK, SPI2_MOSI, SPI2_MISO, SPI2_CS, SPI2_HOLD, SPI2_WP, + UART0_RXD, UART0_TXD, PCIE_PERESET_N, UART1_RXD, UART1_TXD, + UART1_CTS, UART1_RTS, UART2_RXD, UART2_TXD, UART2_CTS, + UART2_RTS, EMMC_DATA_0, EMMC_DATA_1, EMMC_DATA_2, + EMMC_DATA_3, EMMC_DATA_4, EMMC_DATA_5, EMMC_DATA_6, + EMMC_DATA_7, EMMC_CMD, EMMC_CK, EMMC_DSL, EMMC_RSTB, PCM_DTX, + PCM_DRX, PCM_CLK, PCM_FS, MT7531_INT, SMI_MDC, SMI_MDIO, + WF0_DIG_RESETB, WF0_CBA_RESETB, WF0_XO_REQ, WF0_TOP_CLK, + WF0_TOP_DATA, WF0_HB1, WF0_HB2, WF0_HB3, WF0_HB4, WF0_HB0, + WF0_HB0_B, WF0_HB5, WF0_HB6, WF0_HB7, WF0_HB8, WF0_HB9, + WF0_HB10, WF1_DIG_RESETB, WF1_CBA_RESETB, WF1_XO_REQ, + WF1_TOP_CLK, WF1_TOP_DATA, WF1_HB1, WF1_HB2, WF1_HB3, + WF1_HB4, WF1_HB0, WF1_HB0_B, WF1_HB5, WF1_HB6, WF1_HB7, + WF1_HB8] + maxItems: 101 bias-disable: true From a6b9ede1f3dfa5477791ad92d11f60f50998b689 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 5 Sep 2022 19:15:23 -0700 Subject: [PATCH 195/401] PCI: apple: Do not leak reset GPIO on unbind/unload/error The driver allocates reset GPIO in apple_pcie_setup_port() but neither releases the resource, nor uses devm API to have it released automatically. Let's fix this by switching to devm API. While at it let's use generic devm_fwnode_gpiod_get() instead of OF-specific gpiod_get_from_of_node() - this will allow us top stop exporting the latter down the road. Link: https://lore.kernel.org/r/YxatO5OaI2RpxQ2M@google.com Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up") Signed-off-by: Dmitry Torokhov Signed-off-by: Lorenzo Pieralisi Reviewed-by: Hector Martin Acked-by: Marc Zyngier --- drivers/pci/controller/pcie-apple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index a2c3c207a04b..66f37e403a09 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -516,8 +516,8 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, u32 stat, idx; int ret, i; - reset = gpiod_get_from_of_node(np, "reset-gpios", 0, - GPIOD_OUT_LOW, "PERST#"); + reset = devm_fwnode_gpiod_get(pcie->dev, of_fwnode_handle(np), "reset", + GPIOD_OUT_LOW, "PERST#"); if (IS_ERR(reset)) return PTR_ERR(reset); From 612a0f0b93c8c8d3f0ab610c69e0b6678362643b Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 14 Sep 2022 12:30:20 +0200 Subject: [PATCH 196/401] dt-bindings: input: Convert mtk-pmic-keys to DT schema Convert the mtk-pmic-keys to DT schema format. The old binding was missing documentation for key press/release interrupts, even though it was supported in hardware and driver, so support for the same was added during the conversion. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Mattijs Korpershoek Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20220914103021.43593-2-angelogioacchino.delregno@collabora.com Signed-off-by: Dmitry Torokhov --- .../bindings/input/mediatek,pmic-keys.yaml | 113 ++++++++++++++++++ .../bindings/input/mtk-pmic-keys.txt | 46 ------- 2 files changed, 113 insertions(+), 46 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml delete mode 100644 Documentation/devicetree/bindings/input/mtk-pmic-keys.txt diff --git a/Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml b/Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml new file mode 100644 index 000000000000..9d8a0c3aebca --- /dev/null +++ b/Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/mediatek,pmic-keys.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek PMIC Keys + +maintainers: + - Chen Zhong + +allOf: + - $ref: input.yaml# + +description: | + There are two key functions provided by MT6397, MT6323 and other MediaTek + PMICs: pwrkey and homekey. + The key functions are defined as the subnode of the function node provided + by the PMIC that is defined as a Multi-Function Device (MFD). + + For MediaTek MT6323/MT6397 PMIC bindings see + Documentation/devicetree/bindings/mfd/mt6397.txt + +properties: + compatible: + enum: + - mediatek,mt6323-keys + - mediatek,mt6358-keys + - mediatek,mt6397-keys + + power-off-time-sec: true + + mediatek,long-press-mode: + description: | + Key long-press force shutdown setting + 0 - disabled + 1 - pwrkey + 2 - pwrkey+homekey + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + maximum: 2 + +patternProperties: + "^((power|home)|(key-[a-z0-9-]+|[a-z0-9-]+-key))$": + $ref: input.yaml# + + properties: + interrupts: + minItems: 1 + items: + - description: Key press interrupt + - description: Key release interrupt + + interrupt-names: true + + linux-keycodes: + maxItems: 1 + + wakeup-source: true + + required: + - linux,keycodes + + if: + properties: + interrupt-names: + contains: + const: powerkey + then: + properties: + interrupt-names: + minItems: 1 + items: + - const: powerkey + - const: powerkey_r + else: + properties: + interrupt-names: + minItems: 1 + items: + - const: homekey + - const: homekey_r + + unevaluatedProperties: false + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | + #include + #include + + pmic { + compatible = "mediatek,mt6397"; + + keys { + compatible = "mediatek,mt6397-keys"; + mediatek,long-press-mode = <1>; + power-off-time-sec = <0>; + + key-power { + linux,keycodes = ; + wakeup-source; + }; + + key-home { + linux,keycodes = ; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt deleted file mode 100644 index 9d00f2a8e13a..000000000000 --- a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt +++ /dev/null @@ -1,46 +0,0 @@ -MediaTek MT6397/MT6323 PMIC Keys Device Driver - -There are two key functions provided by MT6397/MT6323 PMIC, pwrkey -and homekey. The key functions are defined as the subnode of the function -node provided by MT6397/MT6323 PMIC that is being defined as one kind -of Muti-Function Device (MFD) - -For MT6397/MT6323 MFD bindings see: -Documentation/devicetree/bindings/mfd/mt6397.txt - -Required properties: -- compatible: Should be one of: - - "mediatek,mt6397-keys" - - "mediatek,mt6323-keys" - - "mediatek,mt6358-keys" -- linux,keycodes: See Documentation/devicetree/bindings/input/input.yaml - -Optional Properties: -- wakeup-source: See Documentation/devicetree/bindings/power/wakeup-source.txt -- mediatek,long-press-mode: Long press key shutdown setting, 1 for - pwrkey only, 2 for pwrkey/homekey together, others for disabled. -- power-off-time-sec: See Documentation/devicetree/bindings/input/input.yaml - -Example: - - pmic: mt6397 { - compatible = "mediatek,mt6397"; - - ... - - mt6397keys: mt6397keys { - compatible = "mediatek,mt6397-keys"; - mediatek,long-press-mode = <1>; - power-off-time-sec = <0>; - - power { - linux,keycodes = <116>; - wakeup-source; - }; - - home { - linux,keycodes = <114>; - }; - }; - - }; From 60a884da670119cd5492fe2774a9a3b9d119e045 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 14 Sep 2022 12:30:21 +0200 Subject: [PATCH 197/401] dt-bindings: input: mediatek,pmic-keys: Add compatible for MT6331 keys Add a compatible for the keys found on MT6331 PMIC. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Rob Herring Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20220914103021.43593-3-angelogioacchino.delregno@collabora.com Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml b/Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml index 9d8a0c3aebca..2f72ec418415 100644 --- a/Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml +++ b/Documentation/devicetree/bindings/input/mediatek,pmic-keys.yaml @@ -25,6 +25,7 @@ properties: compatible: enum: - mediatek,mt6323-keys + - mediatek,mt6331-keys - mediatek,mt6358-keys - mediatek,mt6397-keys From a080f9ad604598a4d32ea36fbf96437c92ccacb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 12 Jul 2022 00:59:15 +0200 Subject: [PATCH 198/401] PCI: aardvark: Add support for PCI Bridge Subsystem Vendor ID on emulated bridge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register with Subsystem Device/Vendor ID is at offset 0x2c. Export it via the emulated bridge to enable support for the Subsystem Device/Vendor ID - by reading it in the PCI controller config space and storing it in the emulated bridge control structures, so that it is exposed in the respective PCI capability. After this change Subsystem ID is visible in lspci output at line: Capabilities: [40] Subsystem Link: https://lore.kernel.org/r/20220711225915.13896-1-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/pci-aardvark.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 966c8b48bd96..7cc51cfb8a13 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -33,6 +33,7 @@ #define PCIE_CORE_DEV_ID_REG 0x0 #define PCIE_CORE_CMD_STATUS_REG 0x4 #define PCIE_CORE_DEV_REV_REG 0x8 +#define PCIE_CORE_SSDEV_ID_REG 0x2c #define PCIE_CORE_PCIEXP_CAP 0xc0 #define PCIE_CORE_PCIERR_CAP 0x100 #define PCIE_CORE_ERR_CAPCTL_REG 0x118 @@ -1077,6 +1078,8 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) /* Indicates supports for Completion Retry Status */ bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS); + bridge->subsystem_vendor_id = advk_readl(pcie, PCIE_CORE_SSDEV_ID_REG) & 0xffff; + bridge->subsystem_id = advk_readl(pcie, PCIE_CORE_SSDEV_ID_REG) >> 16; bridge->has_pcie = true; bridge->data = pcie; bridge->ops = &advk_pci_bridge_emul_ops; From 882597aff2d442a52ca173c293939232c2e1ebea Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 14 Sep 2022 07:14:24 -0700 Subject: [PATCH 199/401] Input: auo-pixcir-ts - drop support for platform data Currently there are no users of auo_pixcir_ts_platdata in the mainline, and having it (with legacy gpio numbers) prevents us from converting the driver to gpiod API, so let's drop it. If, in the future, someone wants to use this driver on non-device tree, non-ACPI system, they should use static device properties instead of platform data. Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20220914141428.2201784-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 118 ++++++++++------------ include/linux/input/auo-pixcir-ts.h | 44 -------- 2 files changed, 56 insertions(+), 106 deletions(-) delete mode 100644 include/linux/input/auo-pixcir-ts.h diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index c33e63ca6142..a51d66ebff2b 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -69,6 +68,16 @@ #define AUO_PIXCIR_INT_RELEASE (1 << 4) #define AUO_PIXCIR_INT_ENABLE (1 << 3) #define AUO_PIXCIR_INT_POL_HIGH (1 << 2) + +/* + * Interrupt modes: + * periodical: interrupt is asserted periodicaly + * compare coordinates: interrupt is asserted when coordinates change + * indicate touch: interrupt is asserted during touch + */ +#define AUO_PIXCIR_INT_PERIODICAL 0x00 +#define AUO_PIXCIR_INT_COMP_COORD 0x01 +#define AUO_PIXCIR_INT_TOUCH_IND 0x02 #define AUO_PIXCIR_INT_MODE_MASK 0x03 /* @@ -103,10 +112,14 @@ struct auo_pixcir_ts { struct i2c_client *client; struct input_dev *input; - const struct auo_pixcir_ts_platdata *pdata; + int gpio_int; + int gpio_rst; char phys[32]; - /* special handling for touch_indicate interupt mode */ + unsigned int x_max; + unsigned int y_max; + + /* special handling for touch_indicate interrupt mode */ bool touch_ind_mode; wait_queue_head_t wait; @@ -125,7 +138,6 @@ static int auo_pixcir_collect_data(struct auo_pixcir_ts *ts, struct auo_point_t *point) { struct i2c_client *client = ts->client; - const struct auo_pixcir_ts_platdata *pdata = ts->pdata; uint8_t raw_coord[8]; uint8_t raw_area[4]; int i, ret; @@ -152,8 +164,8 @@ static int auo_pixcir_collect_data(struct auo_pixcir_ts *ts, point[i].coord_y = raw_coord[4 * i + 3] << 8 | raw_coord[4 * i + 2]; - if (point[i].coord_x > pdata->x_max || - point[i].coord_y > pdata->y_max) { + if (point[i].coord_x > ts->x_max || + point[i].coord_y > ts->y_max) { dev_warn(&client->dev, "coordinates (%d,%d) invalid\n", point[i].coord_x, point[i].coord_y); point[i].coord_x = point[i].coord_y = 0; @@ -171,7 +183,6 @@ static int auo_pixcir_collect_data(struct auo_pixcir_ts *ts, static irqreturn_t auo_pixcir_interrupt(int irq, void *dev_id) { struct auo_pixcir_ts *ts = dev_id; - const struct auo_pixcir_ts_platdata *pdata = ts->pdata; struct auo_point_t point[AUO_PIXCIR_REPORT_POINTS]; int i; int ret; @@ -182,7 +193,7 @@ static irqreturn_t auo_pixcir_interrupt(int irq, void *dev_id) /* check for up event in touch touch_ind_mode */ if (ts->touch_ind_mode) { - if (gpio_get_value(pdata->gpio_int) == 0) { + if (gpio_get_value(ts->gpio_int) == 0) { input_mt_sync(ts->input); input_report_key(ts->input, BTN_TOUCH, 0); input_sync(ts->input); @@ -278,11 +289,9 @@ static int auo_pixcir_power_mode(struct auo_pixcir_ts *ts, int mode) return 0; } -static int auo_pixcir_int_config(struct auo_pixcir_ts *ts, - int int_setting) +static int auo_pixcir_int_config(struct auo_pixcir_ts *ts, int int_setting) { struct i2c_client *client = ts->client; - const struct auo_pixcir_ts_platdata *pdata = ts->pdata; int ret; ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_INT_SETTING); @@ -304,7 +313,7 @@ static int auo_pixcir_int_config(struct auo_pixcir_ts *ts, return ret; } - ts->touch_ind_mode = pdata->int_setting == AUO_PIXCIR_INT_TOUCH_IND; + ts->touch_ind_mode = int_setting == AUO_PIXCIR_INT_TOUCH_IND; return 0; } @@ -466,49 +475,41 @@ static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, auo_pixcir_suspend, auo_pixcir_resume); #ifdef CONFIG_OF -static struct auo_pixcir_ts_platdata *auo_pixcir_parse_dt(struct device *dev) +static int auo_pixcir_parse_dt(struct device *dev, struct auo_pixcir_ts *ts) { - struct auo_pixcir_ts_platdata *pdata; struct device_node *np = dev->of_node; if (!np) - return ERR_PTR(-ENOENT); + return -ENOENT; - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); - - pdata->gpio_int = of_get_gpio(np, 0); - if (!gpio_is_valid(pdata->gpio_int)) { + ts->gpio_int = of_get_gpio(np, 0); + if (!gpio_is_valid(ts->gpio_int)) { dev_err(dev, "failed to get interrupt gpio\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } - pdata->gpio_rst = of_get_gpio(np, 1); - if (!gpio_is_valid(pdata->gpio_rst)) { + ts->gpio_rst = of_get_gpio(np, 1); + if (!gpio_is_valid(ts->gpio_rst)) { dev_err(dev, "failed to get reset gpio\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } - if (of_property_read_u32(np, "x-size", &pdata->x_max)) { + if (of_property_read_u32(np, "x-size", &ts->x_max)) { dev_err(dev, "failed to get x-size property\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } - if (of_property_read_u32(np, "y-size", &pdata->y_max)) { + if (of_property_read_u32(np, "y-size", &ts->y_max)) { dev_err(dev, "failed to get y-size property\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } - /* default to asserting the interrupt when the screen is touched */ - pdata->int_setting = AUO_PIXCIR_INT_TOUCH_IND; - - return pdata; + return 0; } #else -static struct auo_pixcir_ts_platdata *auo_pixcir_parse_dt(struct device *dev) +static int auo_pixcir_parse_dt(struct device *dev, struct auo_pixcir_ts *ts) { - return ERR_PTR(-EINVAL); + return -EINVAL; } #endif @@ -516,27 +517,18 @@ static void auo_pixcir_reset(void *data) { struct auo_pixcir_ts *ts = data; - gpio_set_value(ts->pdata->gpio_rst, 0); + gpio_set_value(ts->gpio_rst, 0); } static int auo_pixcir_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct auo_pixcir_ts_platdata *pdata; struct auo_pixcir_ts *ts; struct input_dev *input_dev; int version; int error; - pdata = dev_get_platdata(&client->dev); - if (!pdata) { - pdata = auo_pixcir_parse_dt(&client->dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - } - - ts = devm_kzalloc(&client->dev, - sizeof(struct auo_pixcir_ts), GFP_KERNEL); + ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; @@ -546,7 +538,6 @@ static int auo_pixcir_probe(struct i2c_client *client, return -ENOMEM; } - ts->pdata = pdata; ts->client = client; ts->input = input_dev; ts->touch_ind_mode = 0; @@ -556,6 +547,10 @@ static int auo_pixcir_probe(struct i2c_client *client, snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev)); + error = auo_pixcir_parse_dt(&client->dev, ts); + if (error) + return error; + input_dev->name = "AUO-Pixcir touchscreen"; input_dev->phys = ts->phys; input_dev->id.bustype = BUS_I2C; @@ -569,36 +564,34 @@ static int auo_pixcir_probe(struct i2c_client *client, __set_bit(BTN_TOUCH, input_dev->keybit); /* For single touch */ - input_set_abs_params(input_dev, ABS_X, 0, pdata->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, pdata->y_max, 0, 0); + input_set_abs_params(input_dev, ABS_X, 0, ts->x_max, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, ts->y_max, 0, 0); /* For multi touch */ - input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, - pdata->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, - pdata->y_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, - AUO_PIXCIR_MAX_AREA, 0, 0); - input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, - AUO_PIXCIR_MAX_AREA, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ts->x_max, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, + 0, AUO_PIXCIR_MAX_AREA, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, + 0, AUO_PIXCIR_MAX_AREA, 0, 0); input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); input_set_drvdata(ts->input, ts); - error = devm_gpio_request_one(&client->dev, pdata->gpio_int, + error = devm_gpio_request_one(&client->dev, ts->gpio_int, GPIOF_DIR_IN, "auo_pixcir_ts_int"); if (error) { dev_err(&client->dev, "request of gpio %d failed, %d\n", - pdata->gpio_int, error); + ts->gpio_int, error); return error; } - error = devm_gpio_request_one(&client->dev, pdata->gpio_rst, + error = devm_gpio_request_one(&client->dev, ts->gpio_rst, GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "auo_pixcir_ts_rst"); if (error) { dev_err(&client->dev, "request of gpio %d failed, %d\n", - pdata->gpio_rst, error); + ts->gpio_rst, error); return error; } @@ -619,7 +612,8 @@ static int auo_pixcir_probe(struct i2c_client *client, dev_info(&client->dev, "firmware version 0x%X\n", version); - error = auo_pixcir_int_config(ts, pdata->int_setting); + /* default to asserting the interrupt when the screen is touched */ + error = auo_pixcir_int_config(ts, AUO_PIXCIR_INT_TOUCH_IND); if (error) return error; diff --git a/include/linux/input/auo-pixcir-ts.h b/include/linux/input/auo-pixcir-ts.h deleted file mode 100644 index ed0776997a7a..000000000000 --- a/include/linux/input/auo-pixcir-ts.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Driver for AUO in-cell touchscreens - * - * Copyright (c) 2011 Heiko Stuebner - * - * based on auo_touch.h from Dell Streak kernel - * - * Copyright (c) 2008 QUALCOMM Incorporated. - * Copyright (c) 2008 QUALCOMM USA, INC. - */ - -#ifndef __AUO_PIXCIR_TS_H__ -#define __AUO_PIXCIR_TS_H__ - -/* - * Interrupt modes: - * periodical: interrupt is asserted periodicaly - * compare coordinates: interrupt is asserted when coordinates change - * indicate touch: interrupt is asserted during touch - */ -#define AUO_PIXCIR_INT_PERIODICAL 0x00 -#define AUO_PIXCIR_INT_COMP_COORD 0x01 -#define AUO_PIXCIR_INT_TOUCH_IND 0x02 - -/* - * @gpio_int interrupt gpio - * @int_setting one of AUO_PIXCIR_INT_* - * @init_hw hardwarespecific init - * @exit_hw hardwarespecific shutdown - * @x_max x-resolution - * @y_max y-resolution - */ -struct auo_pixcir_ts_platdata { - int gpio_int; - int gpio_rst; - - int int_setting; - - unsigned int x_max; - unsigned int y_max; -}; - -#endif From a750e24a2f2203d5024a905ce6ea8fcd7a9fd8e2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 14 Sep 2022 07:14:25 -0700 Subject: [PATCH 200/401] Input: auo-pixcir-ts - switch to using gpiod API This switches the driver to gpiod API and drops uses of of_get_gpio() API. Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20220914141428.2201784-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 47 ++++++++++------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index a51d66ebff2b..c3bce9fb2c94 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -10,6 +10,7 @@ * Copyright (c) 2008 QUALCOMM USA, INC. */ +#include #include #include #include @@ -19,9 +20,8 @@ #include #include #include -#include +#include #include -#include /* * Coordinate calculation: @@ -112,8 +112,8 @@ struct auo_pixcir_ts { struct i2c_client *client; struct input_dev *input; - int gpio_int; - int gpio_rst; + struct gpio_desc *gpio_int; + struct gpio_desc *gpio_rst; char phys[32]; unsigned int x_max; @@ -193,7 +193,7 @@ static irqreturn_t auo_pixcir_interrupt(int irq, void *dev_id) /* check for up event in touch touch_ind_mode */ if (ts->touch_ind_mode) { - if (gpio_get_value(ts->gpio_int) == 0) { + if (gpiod_get_value_cansleep(ts->gpio_int) == 0) { input_mt_sync(ts->input); input_report_key(ts->input, BTN_TOUCH, 0); input_sync(ts->input); @@ -482,18 +482,6 @@ static int auo_pixcir_parse_dt(struct device *dev, struct auo_pixcir_ts *ts) if (!np) return -ENOENT; - ts->gpio_int = of_get_gpio(np, 0); - if (!gpio_is_valid(ts->gpio_int)) { - dev_err(dev, "failed to get interrupt gpio\n"); - return -EINVAL; - } - - ts->gpio_rst = of_get_gpio(np, 1); - if (!gpio_is_valid(ts->gpio_rst)) { - dev_err(dev, "failed to get reset gpio\n"); - return -EINVAL; - } - if (of_property_read_u32(np, "x-size", &ts->x_max)) { dev_err(dev, "failed to get x-size property\n"); return -EINVAL; @@ -517,7 +505,7 @@ static void auo_pixcir_reset(void *data) { struct auo_pixcir_ts *ts = data; - gpio_set_value(ts->gpio_rst, 0); + gpiod_set_value_cansleep(ts->gpio_rst, 1); } static int auo_pixcir_probe(struct i2c_client *client, @@ -578,23 +566,28 @@ static int auo_pixcir_probe(struct i2c_client *client, input_set_drvdata(ts->input, ts); - error = devm_gpio_request_one(&client->dev, ts->gpio_int, - GPIOF_DIR_IN, "auo_pixcir_ts_int"); + ts->gpio_int = devm_gpiod_get_index(&client->dev, NULL, 0, GPIOD_IN); + error = PTR_ERR_OR_ZERO(ts->gpio_int); if (error) { - dev_err(&client->dev, "request of gpio %d failed, %d\n", - ts->gpio_int, error); + dev_err(&client->dev, + "request of int gpio failed: %d\n", error); return error; } - error = devm_gpio_request_one(&client->dev, ts->gpio_rst, - GPIOF_DIR_OUT | GPIOF_INIT_HIGH, - "auo_pixcir_ts_rst"); + gpiod_set_consumer_name(ts->gpio_int, "auo_pixcir_ts_int"); + + /* Take the chip out of reset */ + ts->gpio_rst = devm_gpiod_get_index(&client->dev, NULL, 1, + GPIOD_OUT_LOW); + error = PTR_ERR_OR_ZERO(ts->gpio_rst); if (error) { - dev_err(&client->dev, "request of gpio %d failed, %d\n", - ts->gpio_rst, error); + dev_err(&client->dev, + "request of reset gpio failed: %d\n", error); return error; } + gpiod_set_consumer_name(ts->gpio_rst, "auo_pixcir_ts_rst"); + error = devm_add_action_or_reset(&client->dev, auo_pixcir_reset, ts); if (error) { dev_err(&client->dev, "failed to register reset action, %d\n", From 60b7a6d0fdf310f31bc4b9027e3271891b428b0a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 14 Sep 2022 07:14:26 -0700 Subject: [PATCH 201/401] Input: auo-pixcir-ts - do not force rising edge interrupt trigger Instead of hard-coding rising edge as the interrupt trigger, let's rely on the platform (ACPI, DT) to configure the interrupt properly. Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20220914141428.2201784-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index c3bce9fb2c94..4960a50f59ea 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -612,7 +612,7 @@ static int auo_pixcir_probe(struct i2c_client *client, error = devm_request_threaded_irq(&client->dev, client->irq, NULL, auo_pixcir_interrupt, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_ONESHOT, input_dev->name, ts); if (error) { dev_err(&client->dev, "irq %d requested failed, %d\n", From 770a71b23c29c28ed467af488821b4b144ef6953 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 14 Sep 2022 07:14:27 -0700 Subject: [PATCH 202/401] Input: auo-pixcir-ts - switch to using generic device properties Let's use generic device properties API instead of OF-specific one. Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20220914141428.2201784-4-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 40 ++++++----------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 4960a50f59ea..2deae5a6823a 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * Coordinate calculation: @@ -474,33 +475,6 @@ unlock: static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, auo_pixcir_suspend, auo_pixcir_resume); -#ifdef CONFIG_OF -static int auo_pixcir_parse_dt(struct device *dev, struct auo_pixcir_ts *ts) -{ - struct device_node *np = dev->of_node; - - if (!np) - return -ENOENT; - - if (of_property_read_u32(np, "x-size", &ts->x_max)) { - dev_err(dev, "failed to get x-size property\n"); - return -EINVAL; - } - - if (of_property_read_u32(np, "y-size", &ts->y_max)) { - dev_err(dev, "failed to get y-size property\n"); - return -EINVAL; - } - - return 0; -} -#else -static int auo_pixcir_parse_dt(struct device *dev, struct auo_pixcir_ts *ts) -{ - return -EINVAL; -} -#endif - static void auo_pixcir_reset(void *data) { struct auo_pixcir_ts *ts = data; @@ -535,9 +509,15 @@ static int auo_pixcir_probe(struct i2c_client *client, snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev)); - error = auo_pixcir_parse_dt(&client->dev, ts); - if (error) - return error; + if (device_property_read_u32(&client->dev, "x-size", &ts->x_max)) { + dev_err(&client->dev, "failed to get x-size property\n"); + return -EINVAL; + } + + if (device_property_read_u32(&client->dev, "y-size", &ts->y_max)) { + dev_err(&client->dev, "failed to get y-size property\n"); + return -EINVAL; + } input_dev->name = "AUO-Pixcir touchscreen"; input_dev->phys = ts->phys; From 437d49b051e8ca80d2ffa8f3fd98ce58755c2758 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 14 Sep 2022 07:14:28 -0700 Subject: [PATCH 203/401] dt-bindings: input: auo-pixcir-ts: fix gpio and interrupt properties Add proper interrupt trigger and gpio polarity data to the binding example. Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20220914141428.2201784-5-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt index f40f21c642b9..b8db975e9f77 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/auo_pixcir_ts.txt @@ -17,10 +17,10 @@ Example: auo_pixcir_ts@5c { compatible = "auo,auo_pixcir_ts"; reg = <0x5c>; - interrupts = <2 0>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; - gpios = <&gpf 2 0 2>, /* INT */ - <&gpf 5 1 0>; /* RST */ + gpios = <&gpf 2 0 GPIO_LEVEL_HIGH>, /* INT */ + <&gpf 5 1 GPIO_LEVEL_LOW>; /* RST */ x-size = <800>; y-size = <600>; From 460281cf269b02f2caa88ade79c1e7eed29bfe15 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Mon, 19 Sep 2022 06:45:14 +1000 Subject: [PATCH 204/401] xfs: remove the redundant word in comment Just remove the redundant word "being" in comment. Signed-off-by: Zeng Heng Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/xfs_inode_item.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 6e19ece916bf..ca2941ab6cbc 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -550,7 +550,7 @@ xfs_inode_item_push( if (!bp || (ip->i_flags & XFS_ISTALE)) { /* - * Inode item/buffer is being being aborted due to cluster + * Inode item/buffer is being aborted due to cluster * buffer deletion. Trigger a log force to have that operation * completed and items removed from the AIL before the next push * attempt. From 5617104003ae11a1ab383dbd63228b7645c26207 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Mon, 19 Sep 2022 06:46:14 +1000 Subject: [PATCH 205/401] xfs: remove redundant else for clean code "else" is not generally useful after a return, so remove it for clean code. There is no logical changes. Signed-off-by: Zeng Heng Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/xfs_log.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 386b0307aed8..f6e7e4fd72ae 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -226,12 +226,12 @@ xlog_ticket_reservation( if (head == &log->l_write_head) { ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); return tic->t_unit_res; - } else { - if (tic->t_flags & XLOG_TIC_PERM_RESERV) - return tic->t_unit_res * tic->t_cnt; - else - return tic->t_unit_res; } + + if (tic->t_flags & XLOG_TIC_PERM_RESERV) + return tic->t_unit_res * tic->t_cnt; + + return tic->t_unit_res; } STATIC bool From 78b0f58bdfef45aa9f3c7fbbd9b4d41abad6d85f Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Mon, 19 Sep 2022 06:47:14 +1000 Subject: [PATCH 206/401] xfs: clean up "%Ld/%Lu" which doesn't meet C standard The "%Ld" specifier, which represents long long unsigned, doesn't meet C language standard, and even more, it makes people easily mistake with "%ld", which represent long unsigned. So replace "%Ld" with "lld". Do the same with "%Lu". Signed-off-by: Zeng Heng Reviewed-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_inode_fork.c | 4 ++-- fs/xfs/xfs_inode.c | 8 ++++---- fs/xfs/xfs_inode_item_recover.c | 4 ++-- fs/xfs/xfs_stats.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index e56723dc9cd5..49d0d4ea63fc 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -294,7 +294,7 @@ xfs_check_block( else thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr); if (*thispa == *pp) { - xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld", + xfs_warn(mp, "%s: thispa(%d) == pp(%d) %lld", __func__, j, i, (unsigned long long)be64_to_cpu(*thispa)); xfs_err(mp, "%s: ptrs are equal in node\n", diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 9327a4f39206..6b21760184d9 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -78,7 +78,7 @@ xfs_iformat_local( */ if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { xfs_warn(ip->i_mount, - "corrupt inode %Lu (bad size %d for local fork, size = %zd).", + "corrupt inode %llu (bad size %d for local fork, size = %zd).", (unsigned long long) ip->i_ino, size, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)); xfs_inode_verifier_error(ip, -EFSCORRUPTED, @@ -192,7 +192,7 @@ xfs_iformat_btree( XFS_DFORK_SIZE(dip, mp, whichfork) || ifp->if_nextents > ip->i_nblocks) || level == 0 || level > XFS_BM_MAXLEVELS(mp, whichfork)) { - xfs_warn(mp, "corrupt inode %Lu (btree).", + xfs_warn(mp, "corrupt inode %llu (btree).", (unsigned long long) ip->i_ino); xfs_inode_verifier_error(ip, -EFSCORRUPTED, "xfs_iformat_btree", dfp, size, diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 28493c8e9bb2..b3eeeae3afe1 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3119,7 +3119,7 @@ xfs_iflush( if (XFS_TEST_ERROR(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC), mp, XFS_ERRTAG_IFLUSH_1)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad inode %Lu magic number 0x%x, ptr "PTR_FMT, + "%s: Bad inode %llu magic number 0x%x, ptr "PTR_FMT, __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); goto flush_out; } @@ -3129,7 +3129,7 @@ xfs_iflush( ip->i_df.if_format != XFS_DINODE_FMT_BTREE, mp, XFS_ERRTAG_IFLUSH_3)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad regular inode %Lu, ptr "PTR_FMT, + "%s: Bad regular inode %llu, ptr "PTR_FMT, __func__, ip->i_ino, ip); goto flush_out; } @@ -3140,7 +3140,7 @@ xfs_iflush( ip->i_df.if_format != XFS_DINODE_FMT_LOCAL, mp, XFS_ERRTAG_IFLUSH_4)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad directory inode %Lu, ptr "PTR_FMT, + "%s: Bad directory inode %llu, ptr "PTR_FMT, __func__, ip->i_ino, ip); goto flush_out; } @@ -3158,7 +3158,7 @@ xfs_iflush( if (XFS_TEST_ERROR(ip->i_forkoff > mp->m_sb.sb_inodesize, mp, XFS_ERRTAG_IFLUSH_6)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: bad inode %Lu, forkoff 0x%x, ptr "PTR_FMT, + "%s: bad inode %llu, forkoff 0x%x, ptr "PTR_FMT, __func__, ip->i_ino, ip->i_forkoff, ip); goto flush_out; } diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c index d28ffaebd067..0e5dba2343ea 100644 --- a/fs/xfs/xfs_inode_item_recover.c +++ b/fs/xfs/xfs_inode_item_recover.c @@ -321,7 +321,7 @@ xlog_recover_inode_commit_pass2( */ if (XFS_IS_CORRUPT(mp, !xfs_verify_magic16(bp, dip->di_magic))) { xfs_alert(mp, - "%s: Bad inode magic number, dip = "PTR_FMT", dino bp = "PTR_FMT", ino = %Ld", + "%s: Bad inode magic number, dip = "PTR_FMT", dino bp = "PTR_FMT", ino = %lld", __func__, dip, bp, in_f->ilf_ino); error = -EFSCORRUPTED; goto out_release; @@ -329,7 +329,7 @@ xlog_recover_inode_commit_pass2( ldip = item->ri_buf[1].i_addr; if (XFS_IS_CORRUPT(mp, ldip->di_magic != XFS_DINODE_MAGIC)) { xfs_alert(mp, - "%s: Bad inode log record, rec ptr "PTR_FMT", ino %Ld", + "%s: Bad inode log record, rec ptr "PTR_FMT", ino %lld", __func__, item, in_f->ilf_ino); error = -EFSCORRUPTED; goto out_release; diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index 20e0534a772c..881720c4cf70 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -74,7 +74,7 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf) defer_relog += per_cpu_ptr(stats, i)->s.defer_relog; } - len += scnprintf(buf + len, PATH_MAX-len, "xpc %Lu %Lu %Lu\n", + len += scnprintf(buf + len, PATH_MAX-len, "xpc %llu %llu %llu\n", xs_xstrat_bytes, xs_write_bytes, xs_read_bytes); len += scnprintf(buf + len, PATH_MAX-len, "defer_relog %llu\n", defer_relog); From 92b40768c1a4e01e776cb13ab5357a8b5c78e965 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Mon, 19 Sep 2022 06:48:14 +1000 Subject: [PATCH 207/401] xfs: replace unnecessary seq_printf with seq_puts Replace seq_printf with seq_puts when const string in reference, which would avoid to deal with unnecessary string format. Signed-off-by: Zeng Heng Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/xfs_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index 881720c4cf70..90a77cd3ebad 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -125,7 +125,7 @@ static int xqmstat_proc_show(struct seq_file *m, void *v) { int j; - seq_printf(m, "qm"); + seq_puts(m, "qm"); for (j = XFSSTAT_START_XQMSTAT; j < XFSSTAT_END_XQMSTAT; j++) seq_printf(m, " %u", counter_val(xfsstats.xs_stats, j)); seq_putc(m, '\n'); From de94a2e151bed6884b4f21aa518a100ac9e83af2 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Mon, 19 Sep 2022 06:49:14 +1000 Subject: [PATCH 208/401] xfs: simplify if-else condition in xfs_validate_new_dalign "else" is not generally useful after a return, so remove them which makes if condition a bit more clear. There is no logical changes. Signed-off-by: Zeng Heng Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/xfs_mount.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f10c88cee116..e8bb3c2e847e 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -300,26 +300,28 @@ xfs_validate_new_dalign( "alignment check failed: sunit/swidth vs. blocksize(%d)", mp->m_sb.sb_blocksize); return -EINVAL; - } else { - /* - * Convert the stripe unit and width to FSBs. - */ - mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); - if (mp->m_dalign && (mp->m_sb.sb_agblocks % mp->m_dalign)) { - xfs_warn(mp, - "alignment check failed: sunit/swidth vs. agsize(%d)", - mp->m_sb.sb_agblocks); - return -EINVAL; - } else if (mp->m_dalign) { - mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); - } else { - xfs_warn(mp, - "alignment check failed: sunit(%d) less than bsize(%d)", - mp->m_dalign, mp->m_sb.sb_blocksize); - return -EINVAL; - } } + /* + * Convert the stripe unit and width to FSBs. + */ + mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); + if (mp->m_dalign && (mp->m_sb.sb_agblocks % mp->m_dalign)) { + xfs_warn(mp, + "alignment check failed: sunit/swidth vs. agsize(%d)", + mp->m_sb.sb_agblocks); + return -EINVAL; + } + + if (!mp->m_dalign) { + xfs_warn(mp, + "alignment check failed: sunit(%d) less than bsize(%d)", + mp->m_dalign, mp->m_sb.sb_blocksize); + return -EINVAL; + } + + mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); + if (!xfs_has_dalign(mp)) { xfs_warn(mp, "cannot change alignment: superblock does not support data alignment"); From a0ebf8c46d64ba96b413784f88af0a4dca95b6bc Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Mon, 19 Sep 2022 06:50:14 +1000 Subject: [PATCH 209/401] xfs: simplify if-else condition in xfs_reflink_trim_around_shared "else" is not generally useful after a return, so remove it for clean code. There is no logical changes. Signed-off-by: Zeng Heng Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/xfs_reflink.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 251f20ddd368..93bdd25680bc 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -200,7 +200,9 @@ xfs_reflink_trim_around_shared( if (fbno == NULLAGBLOCK) { /* No shared blocks at all. */ return 0; - } else if (fbno == agbno) { + } + + if (fbno == agbno) { /* * The start of this extent is shared. Truncate the * mapping at the end of the shared region so that a @@ -210,16 +212,16 @@ xfs_reflink_trim_around_shared( irec->br_blockcount = flen; *shared = true; return 0; - } else { - /* - * There's a shared extent midway through this extent. - * Truncate the mapping at the start of the shared - * extent so that a subsequent iteration starts at the - * start of the shared region. - */ - irec->br_blockcount = fbno - agbno; - return 0; } + + /* + * There's a shared extent midway through this extent. + * Truncate the mapping at the start of the shared + * extent so that a subsequent iteration starts at the + * start of the shared region. + */ + irec->br_blockcount = fbno - agbno; + return 0; } int From 8838dafed5d93b3e8a403e57838a43fb09dd6e61 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Mon, 19 Sep 2022 06:51:14 +1000 Subject: [PATCH 210/401] xfs: missing space in xfs trace log Add space between arguments would help someone to locate the key words they want, so break quoted strings at a space character. Such as below: [Before] kworker/1:0-280 [001] ..... 600.782135: xfs_bunmap: dev 7:0 ino 0x85 disize 0x0 fileoff 0x0 fsbcount 0x400000001fffffflags ATTRFORK ... [After] kworker/1:2-564 [001] ..... 23817.906160: xfs_bunmap: dev 7:0 ino 0x85 disize 0x0 fileoff 0x0 fsbcount 0x400000001fffff flags ATTRFORK ... Signed-off-by: Zeng Heng Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/xfs_trace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index f9057af6e0c8..cb7c81ba7fa3 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1170,7 +1170,7 @@ DECLARE_EVENT_CLASS(xfs_dqtrx_class, __entry->ino_res_used = qtrx->qt_ino_res_used; __entry->icount_delta = qtrx->qt_icount_delta; ), - TP_printk("dev %d:%d dquot id 0x%x type %s flags %s" + TP_printk("dev %d:%d dquot id 0x%x type %s flags %s " "blk_res %llu bcount_delta %lld delbcnt_delta %lld " "rtblk_res %llu rtblk_res_used %llu rtbcount_delta %lld delrtb_delta %lld " "ino_res %llu ino_res_used %llu icount_delta %lld", @@ -1602,7 +1602,7 @@ TRACE_EVENT(xfs_bunmap, __entry->caller_ip = caller_ip; __entry->flags = flags; ), - TP_printk("dev %d:%d ino 0x%llx disize 0x%llx fileoff 0x%llx fsbcount 0x%llx" + TP_printk("dev %d:%d ino 0x%llx disize 0x%llx fileoff 0x%llx fsbcount 0x%llx " "flags %s caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, From abda5271f8ec6e9a84ae8129ddc59226c89def7a Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Mon, 19 Sep 2022 06:52:14 +1000 Subject: [PATCH 211/401] xfs: Remove the unneeded result variable Return the value xfs_dir_cilookup_result() directly instead of storing it in another redundant variable. Reported-by: Zeal Robot Signed-off-by: ye xingchen Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_dir2_sf.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index 003812fd7d35..8cd37e6e9d38 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -865,7 +865,6 @@ xfs_dir2_sf_lookup( struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; int i; /* entry index */ - int error; xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ enum xfs_dacmp cmp; /* comparison result */ @@ -929,8 +928,7 @@ xfs_dir2_sf_lookup( if (!ci_sfep) return -ENOENT; /* otherwise process the CI match as required by the caller */ - error = xfs_dir_cilookup_result(args, ci_sfep->name, ci_sfep->namelen); - return error; + return xfs_dir_cilookup_result(args, ci_sfep->name, ci_sfep->namelen); } /* From b0463b9dd7030a766133ad2f1571f97f204d7bdf Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Mon, 19 Sep 2022 06:53:14 +1000 Subject: [PATCH 212/401] xfs: remove xfs_setattr_time() declaration xfs_setattr_time() has been removed since commit e014f37db1a2 ("xfs: use setattr_copy to set vfs inode attributes"), so remove it. Signed-off-by: Gaosheng Cui Reviewed-by: Carlos Maiolino Signed-off-by: Dave Chinner --- fs/xfs/xfs_iops.h | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/xfs/xfs_iops.h b/fs/xfs/xfs_iops.h index cb5fc68c9ea0..e570dcb5df8d 100644 --- a/fs/xfs/xfs_iops.h +++ b/fs/xfs/xfs_iops.h @@ -13,7 +13,6 @@ extern const struct file_operations xfs_dir_file_operations; extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size); -extern void xfs_setattr_time(struct xfs_inode *ip, struct iattr *iattr); int xfs_vn_setattr_size(struct user_namespace *mnt_userns, struct dentry *dentry, struct iattr *vap); From 42b7cc11023d0aa19dbf4d60bb3b8f7423d24a24 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Mon, 19 Sep 2022 06:54:14 +1000 Subject: [PATCH 213/401] xfs: port to vfs{g,u}id_t and associated helpers A while ago we introduced a dedicated vfs{g,u}id_t type in commit 1e5267cd0895 ("mnt_idmapping: add vfs{g,u}id_t"). We already switched over a good part of the VFS. Ultimately we will remove all legacy idmapped mount helpers that operate only on k{g,u}id_t in favor of the new type safe helpers that operate on vfs{g,u}id_t. Signed-off-by: Christian Brauner (Microsoft) Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_inode.c | 5 ++--- fs/xfs/xfs_iops.c | 6 ++++-- fs/xfs/xfs_itable.c | 8 ++++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index b3eeeae3afe1..c000b74dd203 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -835,9 +835,8 @@ xfs_init_new_inode( * ID or one of the supplementary group IDs, the S_ISGID bit is cleared * (and only if the irix_sgid_inherit compatibility variable is set). */ - if (irix_sgid_inherit && - (inode->i_mode & S_ISGID) && - !in_group_p(i_gid_into_mnt(mnt_userns, inode))) + if (irix_sgid_inherit && (inode->i_mode & S_ISGID) && + !vfsgid_in_group_p(i_gid_into_vfsgid(mnt_userns, inode))) inode->i_mode &= ~S_ISGID; ip->i_disk_size = 0; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 45518b8c613c..5d670c85dcc2 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -558,6 +558,8 @@ xfs_vn_getattr( struct inode *inode = d_inode(path->dentry); struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; + vfsuid_t vfsuid = i_uid_into_vfsuid(mnt_userns, inode); + vfsgid_t vfsgid = i_gid_into_vfsgid(mnt_userns, inode); trace_xfs_getattr(ip); @@ -568,8 +570,8 @@ xfs_vn_getattr( stat->dev = inode->i_sb->s_dev; stat->mode = inode->i_mode; stat->nlink = inode->i_nlink; - stat->uid = i_uid_into_mnt(mnt_userns, inode); - stat->gid = i_gid_into_mnt(mnt_userns, inode); + stat->uid = vfsuid_into_kuid(vfsuid); + stat->gid = vfsgid_into_kgid(vfsgid); stat->ino = ip->i_ino; stat->atime = inode->i_atime; stat->mtime = inode->i_mtime; diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 36312b00b164..a1c2bcf65d37 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -66,6 +66,8 @@ xfs_bulkstat_one_int( struct xfs_bulkstat *buf = bc->buf; xfs_extnum_t nextents; int error = -EINVAL; + vfsuid_t vfsuid; + vfsgid_t vfsgid; if (xfs_internal_inum(mp, ino)) goto out_advance; @@ -81,14 +83,16 @@ xfs_bulkstat_one_int( ASSERT(ip != NULL); ASSERT(ip->i_imap.im_blkno != 0); inode = VFS_I(ip); + vfsuid = i_uid_into_vfsuid(mnt_userns, inode); + vfsgid = i_gid_into_vfsgid(mnt_userns, inode); /* xfs_iget returns the following without needing * further change. */ buf->bs_projectid = ip->i_projid; buf->bs_ino = ino; - buf->bs_uid = from_kuid(sb_userns, i_uid_into_mnt(mnt_userns, inode)); - buf->bs_gid = from_kgid(sb_userns, i_gid_into_mnt(mnt_userns, inode)); + buf->bs_uid = from_kuid(sb_userns, vfsuid_into_kuid(vfsuid)); + buf->bs_gid = from_kgid(sb_userns, vfsgid_into_kgid(vfsgid)); buf->bs_size = ip->i_disk_size; buf->bs_nlink = inode->i_nlink; From dc256418235a8355fbdf83b90048d8704b8d1654 Mon Sep 17 00:00:00 2001 From: Zhiqiang Liu Date: Mon, 19 Sep 2022 06:55:14 +1000 Subject: [PATCH 214/401] xfs: do not need to check return value of xlog_kvmalloc() In xfs_attri_log_nameval_alloc(), xlog_kvmalloc() is called to alloc memory, which will always return successfully, so we donot need to check return value. Reviewed-by: Eric Sandeen Signed-off-by: Zhiqiang Liu Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/xfs_attr_item.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 5077a7ad5646..cf5ce607dc05 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -86,8 +86,6 @@ xfs_attri_log_nameval_alloc( */ nv = xlog_kvmalloc(sizeof(struct xfs_attri_log_nameval) + name_len + value_len); - if (!nv) - return nv; nv->name.i_addr = nv + 1; nv->name.i_len = name_len; @@ -441,8 +439,6 @@ xfs_attr_create_intent( attr->xattri_nameval = xfs_attri_log_nameval_alloc(args->name, args->namelen, args->value, args->valuelen); } - if (!attr->xattri_nameval) - return ERR_PTR(-ENOMEM); attrip = xfs_attri_init(mp, attr->xattri_nameval); xfs_trans_add_item(tp, &attrip->attri_item); @@ -762,8 +758,6 @@ xlog_recover_attri_commit_pass2( nv = xfs_attri_log_nameval_alloc(attr_name, attri_formatp->alfi_name_len, attr_value, attri_formatp->alfi_value_len); - if (!nv) - return -ENOMEM; attrip = xfs_attri_init(mp, nv); error = xfs_attri_copy_format(&item->ri_buf[0], &attrip->attri_format); From e5ec1f9da84324d01b7b8ec3a8bf50e8430b99a7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 17 Sep 2022 22:30:35 +0200 Subject: [PATCH 215/401] pinctrl: nomadik: Dereference gpio_chip properly The irq data passed to irc_chip handlers i the struct gpio_chip and nothing else. We are just lucky that the nomadik chip pointer is first in the struct. Use the proper dereferencing and helpers. Reported-by: Marc Zyngier Acked-by: Marc Zyngier Link: https://lore.kernel.org/r/20220917203036.167607-1-linus.walleij@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 30 +++++++++-------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 58c7ac8c7d4d..54852775d653 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -608,8 +608,8 @@ static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, static void nmk_gpio_irq_ack(struct irq_data *d) { - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(chip); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); clk_enable(nmk_chip->clk); writel(BIT(d->hwirq), nmk_chip->addr + NMK_GPIO_IC); @@ -677,13 +677,10 @@ static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) { - struct nmk_gpio_chip *nmk_chip; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); unsigned long flags; - nmk_chip = irq_data_get_irq_chip_data(d); - if (!nmk_chip) - return -EINVAL; - clk_enable(nmk_chip->clk); spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); spin_lock(&nmk_chip->lock); @@ -712,13 +709,10 @@ static void nmk_gpio_irq_unmask(struct irq_data *d) static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) { - struct nmk_gpio_chip *nmk_chip; + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); unsigned long flags; - nmk_chip = irq_data_get_irq_chip_data(d); - if (!nmk_chip) - return -EINVAL; - clk_enable(nmk_chip->clk); spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); spin_lock(&nmk_chip->lock); @@ -740,14 +734,12 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) { + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); bool enabled = !irqd_irq_disabled(d); bool wake = irqd_is_wakeup_set(d); - struct nmk_gpio_chip *nmk_chip; unsigned long flags; - nmk_chip = irq_data_get_irq_chip_data(d); - if (!nmk_chip) - return -EINVAL; if (type & IRQ_TYPE_LEVEL_HIGH) return -EINVAL; if (type & IRQ_TYPE_LEVEL_LOW) @@ -784,7 +776,8 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) static unsigned int nmk_gpio_irq_startup(struct irq_data *d) { - struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); clk_enable(nmk_chip->clk); nmk_gpio_irq_unmask(d); @@ -793,7 +786,8 @@ static unsigned int nmk_gpio_irq_startup(struct irq_data *d) static void nmk_gpio_irq_shutdown(struct irq_data *d) { - struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); nmk_gpio_irq_mask(d); clk_disable(nmk_chip->clk); From 42da71add478b5a6f82520181a4010a3823bced0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 17 Sep 2022 22:30:36 +0200 Subject: [PATCH 216/401] pinctrl: nomadik: Make gpio irqchip immutable This makes the Nomadik GPIO irqchip immutable. Tested on the Samsung Galaxy SIII mini GT-I8190. Cc: Marc Zyngier Acked-by: Marc Zyngier Link: https://lore.kernel.org/r/20220917203036.167607-2-linus.walleij@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 59 ++++++++++++++--------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 54852775d653..21e6ad1c57b2 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -244,7 +244,6 @@ enum nmk_gpio_slpm { struct nmk_gpio_chip { struct gpio_chip chip; - struct irq_chip irqchip; void __iomem *addr; struct clk *clk; unsigned int bank; @@ -675,10 +674,9 @@ static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip, __nmk_gpio_irq_modify(nmk_chip, offset, WAKE, on); } -static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) +static void nmk_gpio_irq_maskunmask(struct nmk_gpio_chip *nmk_chip, + struct irq_data *d, bool enable) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); unsigned long flags; clk_enable(nmk_chip->clk); @@ -693,18 +691,24 @@ static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) spin_unlock(&nmk_chip->lock); spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); clk_disable(nmk_chip->clk); - - return 0; } static void nmk_gpio_irq_mask(struct irq_data *d) { - nmk_gpio_irq_maskunmask(d, false); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + nmk_gpio_irq_maskunmask(nmk_chip, d, false); + gpiochip_disable_irq(gc, irqd_to_hwirq(d)); } static void nmk_gpio_irq_unmask(struct irq_data *d) { - nmk_gpio_irq_maskunmask(d, true); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + gpiochip_enable_irq(gc, irqd_to_hwirq(d)); + nmk_gpio_irq_maskunmask(nmk_chip, d, true); } static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) @@ -1072,13 +1076,34 @@ static struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np, return nmk_chip; } +static void nmk_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct nmk_gpio_chip *nmk_chip = gpiochip_get_data(gc); + + seq_printf(p, "nmk%u-%u-%u", nmk_chip->bank, + gc->base, gc->base + gc->ngpio - 1); +} + +static const struct irq_chip nmk_irq_chip = { + .irq_ack = nmk_gpio_irq_ack, + .irq_mask = nmk_gpio_irq_mask, + .irq_unmask = nmk_gpio_irq_unmask, + .irq_set_type = nmk_gpio_irq_set_type, + .irq_set_wake = nmk_gpio_irq_set_wake, + .irq_startup = nmk_gpio_irq_startup, + .irq_shutdown = nmk_gpio_irq_shutdown, + .irq_print_chip = nmk_gpio_irq_print_chip, + .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static int nmk_gpio_probe(struct platform_device *dev) { struct device_node *np = dev->dev.of_node; struct nmk_gpio_chip *nmk_chip; struct gpio_chip *chip; struct gpio_irq_chip *girq; - struct irq_chip *irqchip; bool supports_sleepmode; int irq; int ret; @@ -1119,22 +1144,8 @@ static int nmk_gpio_probe(struct platform_device *dev) chip->can_sleep = false; chip->owner = THIS_MODULE; - irqchip = &nmk_chip->irqchip; - irqchip->irq_ack = nmk_gpio_irq_ack; - irqchip->irq_mask = nmk_gpio_irq_mask; - irqchip->irq_unmask = nmk_gpio_irq_unmask; - irqchip->irq_set_type = nmk_gpio_irq_set_type; - irqchip->irq_set_wake = nmk_gpio_irq_set_wake; - irqchip->irq_startup = nmk_gpio_irq_startup; - irqchip->irq_shutdown = nmk_gpio_irq_shutdown; - irqchip->flags = IRQCHIP_MASK_ON_SUSPEND; - irqchip->name = kasprintf(GFP_KERNEL, "nmk%u-%u-%u", - dev->id, - chip->base, - chip->base + chip->ngpio - 1); - girq = &chip->irq; - girq->chip = irqchip; + gpio_irq_chip_set_chip(girq, &nmk_irq_chip); girq->parent_handler = nmk_gpio_irq_handler; girq->num_parents = 1; girq->parents = devm_kcalloc(&dev->dev, 1, From 1c2eb18ef6739c89d13a9b36d19c68b84ab37625 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Mon, 19 Sep 2022 08:54:35 +0200 Subject: [PATCH 217/401] pinctrl: nomadik: remove dead code after DB8540 pinctrl removal Commit b6d09f780761 ("pinctrl: nomadik: Drop U8540/9540 support") removes the DB8540 pin controller driver and its config PINCTRL_DB8540. There is some code left-over in the generic nomadik pinctrl driver, i.e., drivers/pinctrl/nomadik/pinctrl-nomadik.{ch}, that is still around for the removed DB8540 pin controller driver. Remove this remaining dead code. This issue was discovered with ./scripts/checkkconfigsymbols.py. Signed-off-by: Lukas Bulwahn Link: https://lore.kernel.org/r/20220919065435.27747-1-lukas.bulwahn@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 6 ------ drivers/pinctrl/nomadik/pinctrl-nomadik.h | 14 -------------- 2 files changed, 20 deletions(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 21e6ad1c57b2..f7d02513d8cc 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -1807,10 +1807,6 @@ static const struct of_device_id nmk_pinctrl_match[] = { .compatible = "stericsson,db8500-pinctrl", .data = (void *)PINCTRL_NMK_DB8500, }, - { - .compatible = "stericsson,db8540-pinctrl", - .data = (void *)PINCTRL_NMK_DB8540, - }, {}, }; @@ -1861,8 +1857,6 @@ static int nmk_pinctrl_probe(struct platform_device *pdev) nmk_pinctrl_stn8815_init(&npct->soc); if (version == PINCTRL_NMK_DB8500) nmk_pinctrl_db8500_init(&npct->soc); - if (version == PINCTRL_NMK_DB8540) - nmk_pinctrl_db8540_init(&npct->soc); /* * Since we depend on the GPIO chips to provide clock and register base diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h index 820f07f4db32..84e297757335 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.h +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.h @@ -5,7 +5,6 @@ /* Package definitions */ #define PINCTRL_NMK_STN8815 0 #define PINCTRL_NMK_DB8500 1 -#define PINCTRL_NMK_DB8540 2 /* Alternate functions: function C is set in hw by setting both A and B */ #define NMK_GPIO_ALT_GPIO 0 @@ -173,17 +172,4 @@ nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc) #endif -#ifdef CONFIG_PINCTRL_DB8540 - -void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc); - -#else - -static inline void -nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc) -{ -} - -#endif - #endif /* PINCTRL_PINCTRL_NOMADIK_H */ From 4af95d0937144d6df1b4f262d311cf2e0ace569a Mon Sep 17 00:00:00 2001 From: David Collins Date: Mon, 12 Sep 2022 14:06:23 -0700 Subject: [PATCH 218/401] pinctrl: qcom: spmi-gpio: add support for LV_VIN2 and MV_VIN3 subtypes Add support for SPMI PMIC GPIO subtypes GPIO_LV_VIN2 and GPIO_MV_VIN3. GPIO_LV_VIN2 GPIOs support two input reference voltages: VIN0 and VIN1. These are typically connected to 1.8 V and 1.2 V supplies respectively. GPIO_MV_VIN3 GPIOs support three input reference voltages: VIN0, VIN1, and VIN2. These are typically connected to Vph, 1.8 V, and 1.2 V supplies respectively. Signed-off-by: David Collins Signed-off-by: Anjelique Melendez Link: https://lore.kernel.org/r/20220912210624.4527-2-quic_amelende@quicinc.com Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 8ba3d5021f0b..9534bdffe6fb 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2014, 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -36,6 +37,8 @@ #define PMIC_GPIO_SUBTYPE_GPIOC_8CH 0xd #define PMIC_GPIO_SUBTYPE_GPIO_LV 0x10 #define PMIC_GPIO_SUBTYPE_GPIO_MV 0x11 +#define PMIC_GPIO_SUBTYPE_GPIO_LV_VIN2 0x12 +#define PMIC_GPIO_SUBTYPE_GPIO_MV_VIN3 0x13 #define PMIC_MPP_REG_RT_STS 0x10 #define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1 @@ -822,6 +825,16 @@ static int pmic_gpio_populate(struct pmic_gpio_state *state, pad->have_buffer = true; pad->lv_mv_type = true; break; + case PMIC_GPIO_SUBTYPE_GPIO_LV_VIN2: + pad->num_sources = 2; + pad->have_buffer = true; + pad->lv_mv_type = true; + break; + case PMIC_GPIO_SUBTYPE_GPIO_MV_VIN3: + pad->num_sources = 3; + pad->have_buffer = true; + pad->lv_mv_type = true; + break; default: dev_err(state->dev, "unknown GPIO type 0x%x\n", subtype); return -ENODEV; From 723e8462a4fe7138bacac528dcdc7d4484c690fd Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 12 Sep 2022 14:06:25 -0700 Subject: [PATCH 219/401] pinctrl: qcom: spmi-gpio: Fix the GPIO strength mapping The SPMI based PMICs have the HIGH and LOW GPIO output strength mappings interchanged, fix them. Signed-off-by: Anjelique Melendez Link: https://lore.kernel.org/r/20220912210624.4527-3-quic_amelende@quicinc.com Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 27 ++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 9534bdffe6fb..8f4235f878d5 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -101,6 +101,9 @@ #define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS 1 #define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS 2 +#define PMIC_GPIO_OUT_STRENGTH_LOW 1 +#define PMIC_GPIO_OUT_STRENGTH_HIGH 3 + /* PMIC_GPIO_REG_EN_CTL */ #define PMIC_GPIO_REG_MASTER_EN_SHIFT 7 @@ -439,7 +442,17 @@ static int pmic_gpio_config_get(struct pinctrl_dev *pctldev, arg = pad->pullup; break; case PMIC_GPIO_CONF_STRENGTH: - arg = pad->strength; + switch (pad->strength) { + case PMIC_GPIO_OUT_STRENGTH_HIGH: + arg = PMIC_GPIO_STRENGTH_HIGH; + break; + case PMIC_GPIO_OUT_STRENGTH_LOW: + arg = PMIC_GPIO_STRENGTH_LOW; + break; + default: + arg = pad->strength; + break; + } break; case PMIC_GPIO_CONF_ATEST: arg = pad->atest; @@ -526,7 +539,17 @@ static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin, case PMIC_GPIO_CONF_STRENGTH: if (arg > PMIC_GPIO_STRENGTH_LOW) return -EINVAL; - pad->strength = arg; + switch (arg) { + case PMIC_GPIO_STRENGTH_HIGH: + pad->strength = PMIC_GPIO_OUT_STRENGTH_HIGH; + break; + case PMIC_GPIO_STRENGTH_LOW: + pad->strength = PMIC_GPIO_OUT_STRENGTH_LOW; + break; + default: + pad->strength = arg; + break; + } break; case PMIC_GPIO_CONF_ATEST: if (!pad->lv_mv_type || arg > 4) From 3d46ff83df39a62a6b40b55479bfea23838add26 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Mon, 12 Sep 2022 14:06:27 -0700 Subject: [PATCH 220/401] pinctrl: qcom: spmi-gpio: Add compatible for PM7250B Add support for qcom,pm7250b-gpio variant. Signed-off-by: Jishnu Prakash Signed-off-by: David Collins Signed-off-by: Anjelique Melendez Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220912210624.4527-4-quic_amelende@quicinc.com Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 8f4235f878d5..8c31a8f6b7e4 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1201,6 +1201,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm6350-gpio", .data = (void *) 9 }, + { .compatible = "qcom,pm7250b-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm7325-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm8005-gpio", .data = (void *) 4 }, { .compatible = "qcom,pm8008-gpio", .data = (void *) 2 }, From a72be048b71c10475d169d3951c49fb8a6a803e3 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 12 Sep 2022 14:06:29 -0700 Subject: [PATCH 221/401] dt-bindings: qcom-pmic-gpio: Add PM7250B and PM8450 bindings Update the Qualcomm Technologies, Inc. PMIC GPIO binding documentation to include compatible strings for PM7250B and PM8450 PMICs. Signed-off-by: Anjelique Melendez Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220912210624.4527-5-quic_amelende@quicinc.com Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml index 694898f382be..29dd503f9522 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml @@ -24,6 +24,7 @@ properties: - qcom,pm6150-gpio - qcom,pm6150l-gpio - qcom,pm6350-gpio + - qcom,pm7250b-gpio - qcom,pm7325-gpio - qcom,pm8005-gpio - qcom,pm8008-gpio @@ -231,6 +232,7 @@ allOf: enum: - qcom,pm660l-gpio - qcom,pm6150l-gpio + - qcom,pm7250b-gpio - qcom,pm8038-gpio - qcom,pm8150b-gpio - qcom,pm8150l-gpio @@ -392,6 +394,7 @@ $defs: - gpio1-gpio10 for pm6150 - gpio1-gpio12 for pm6150l - gpio1-gpio9 for pm6350 + - gpio1-gpio12 for pm7250b - gpio1-gpio10 for pm7325 - gpio1-gpio4 for pm8005 - gpio1-gpio2 for pm8008 @@ -407,6 +410,7 @@ $defs: - gpio1-gpio10 for pm8350 - gpio1-gpio8 for pm8350b - gpio1-gpio9 for pm8350c + - gpio1-gpio4 for pm8450 - gpio1-gpio38 for pm8917 - gpio1-gpio44 for pm8921 - gpio1-gpio36 for pm8941 From e01bae16a7d68931f0450cb079479c4a8f56d3e3 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 16 Sep 2022 22:03:29 +0800 Subject: [PATCH 222/401] PCI/P2PDMA: Use for_each_pci_dev() helper Use for_each_pci_dev() instead of open-coding it. No functional change. Link: https://lore.kernel.org/r/20220916140329.679633-1-yangyingliang@huawei.com Signed-off-by: Yang Yingliang Signed-off-by: Bjorn Helgaas Reviewed-by: Logan Gunthorpe --- drivers/pci/p2pdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index 4496a7c5c478..88dc66ee1c46 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c @@ -649,7 +649,7 @@ struct pci_dev *pci_p2pmem_find_many(struct device **clients, int num_clients) if (!closest_pdevs) return NULL; - while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) { + for_each_pci_dev(pdev) { if (!pci_has_p2pmem(pdev)) continue; From 790cf9e3da3f16d65d389d714f6e18f27cf18704 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 17 Sep 2022 20:20:15 +0800 Subject: [PATCH 223/401] pinctrl: stm32: Switch to use dev_err_probe() helper In the probe path, dev_err() can be replace with dev_err_probe() which will check if error code is -EPROBE_DEFER and prints the error name. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20220917122015.1893880-1-yangyingliang@huawei.com Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 14bcca73238a..e485506ea599 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1603,10 +1603,9 @@ int stm32_pctl_probe(struct platform_device *pdev) bank->clk = of_clk_get_by_name(np, NULL); if (IS_ERR(bank->clk)) { - if (PTR_ERR(bank->clk) != -EPROBE_DEFER) - dev_err(dev, "failed to get clk (%ld)\n", PTR_ERR(bank->clk)); fwnode_handle_put(child); - return PTR_ERR(bank->clk); + return dev_err_probe(dev, PTR_ERR(bank->clk), + "failed to get clk\n"); } i++; } From 35b871f72a5a06dc5a328427a437797ad99c0696 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 17 Sep 2022 20:22:08 +0800 Subject: [PATCH 224/401] pinctrl: sunxi: sun50i-h5: Switch to use dev_err_probe() helper In the probe path, dev_err() can be replace with dev_err_probe() which will check if error code is -EPROBE_DEFER and and prints the error name. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20220917122208.1894769-1-yangyingliang@huawei.com Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sun50i-h5.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-h5.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-h5.c index 31d62bbb7f43..96a350e70668 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun50i-h5.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-h5.c @@ -551,12 +551,9 @@ static int sun50i_h5_pinctrl_probe(struct platform_device *pdev) int ret; ret = platform_irq_count(pdev); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "Couldn't determine irq count: %pe\n", - ERR_PTR(ret)); - return ret; - } + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, + "Couldn't determine irq count\n"); switch (ret) { case 2: From 56e380cfcd82a228dc006902b88cf1adaf9851dc Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 16 Sep 2022 23:54:48 +0300 Subject: [PATCH 225/401] pinctrl: cy8c95x0: Lock register accesses in cy8c95x0_set_mux() It seems that cy8c95x0_set_mux() missed serialization of IO access. And its implementation looks half-baked. Add locking to the function. Fixes: e6cbbe42944d ("pinctrl: Add Cypress cy8c95x0 support") Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220916205450.86278-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 79f73d364f3f..75be06d29dc1 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1152,8 +1152,13 @@ static int cy8c95x0_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, unsigned int group) { struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); + int ret; - return cy8c95x0_pinmux_cfg(chip, selector, group); + mutex_lock(&chip->i2c_lock); + ret = cy8c95x0_pinmux_cfg(chip, selector, group); + mutex_unlock(&chip->i2c_lock); + + return ret; } static const struct pinmux_ops cy8c95x0_pmxops = { From d6afdf8826ef4c719ab78d33e932dc6ad9dedb35 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 16 Sep 2022 23:54:49 +0300 Subject: [PATCH 226/401] pinctrl: cy8c95x0: Drop atomicity on operations on push_pull The push_pull member is always accessed under the mutex, hence no need to use atomic operations on it. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220916205450.86278-2-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 75be06d29dc1..367a9386dfb7 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -573,7 +573,8 @@ static int cy8c95x0_gpio_direction_input(struct gpio_chip *gc, unsigned int off) ret = regmap_write_bits(chip->regmap, CY8C95X0_DRV_HIZ, bit, bit); if (ret) goto out; - clear_bit(off, chip->push_pull); + + __clear_bit(off, chip->push_pull); } out: @@ -775,27 +776,27 @@ static int cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl *chip, switch (param) { case PIN_CONFIG_BIAS_PULL_UP: - clear_bit(off, chip->push_pull); + __clear_bit(off, chip->push_pull); reg = CY8C95X0_DRV_PU; break; case PIN_CONFIG_BIAS_PULL_DOWN: - clear_bit(off, chip->push_pull); + __clear_bit(off, chip->push_pull); reg = CY8C95X0_DRV_PD; break; case PIN_CONFIG_BIAS_DISABLE: - clear_bit(off, chip->push_pull); + __clear_bit(off, chip->push_pull); reg = CY8C95X0_DRV_HIZ; break; case PIN_CONFIG_DRIVE_OPEN_DRAIN: - clear_bit(off, chip->push_pull); + __clear_bit(off, chip->push_pull); reg = CY8C95X0_DRV_ODL; break; case PIN_CONFIG_DRIVE_OPEN_SOURCE: - clear_bit(off, chip->push_pull); + __clear_bit(off, chip->push_pull); reg = CY8C95X0_DRV_ODH; break; case PIN_CONFIG_DRIVE_PUSH_PULL: - set_bit(off, chip->push_pull); + __set_bit(off, chip->push_pull); reg = CY8C95X0_DRV_PP_FAST; break; case PIN_CONFIG_MODE_PWM: From ee6cac37368b7ec2b3f798fb7d6d4ce7a62db537 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 16 Sep 2022 23:54:50 +0300 Subject: [PATCH 227/401] pinctrl: cy8c95x0: Align function names in cy8c95x0_pmxops Align the function names in the cy8c95x0_pmxops() to follow the struct pinmux_ops members naming schema. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220916205450.86278-3-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-cy8c95x0.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 367a9386dfb7..68509a2301b8 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -1103,7 +1103,7 @@ static const struct pinctrl_ops cy8c95x0_pinctrl_ops = { .pin_dbg_show = cy8c95x0_pin_dbg_show, }; -static const char *cy8c95x0_get_functions_name(struct pinctrl_dev *pctldev, unsigned int selector) +static const char *cy8c95x0_get_function_name(struct pinctrl_dev *pctldev, unsigned int selector) { return cy8c95x0_get_fname(selector); } @@ -1113,9 +1113,9 @@ static int cy8c95x0_get_functions_count(struct pinctrl_dev *pctldev) return 2; } -static int cy8c95x0_get_groups(struct pinctrl_dev *pctldev, unsigned int selector, - const char * const **groups, - unsigned int * const num_groups) +static int cy8c95x0_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector, + const char * const **groups, + unsigned int * const num_groups) { struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev); @@ -1164,8 +1164,8 @@ static int cy8c95x0_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, static const struct pinmux_ops cy8c95x0_pmxops = { .get_functions_count = cy8c95x0_get_functions_count, - .get_function_name = cy8c95x0_get_functions_name, - .get_function_groups = cy8c95x0_get_groups, + .get_function_name = cy8c95x0_get_function_name, + .get_function_groups = cy8c95x0_get_function_groups, .set_mux = cy8c95x0_set_mux, .strict = true, }; From 670f8ce56dd0632dc29a0322e188cc73ce3c6b92 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Wed, 17 Aug 2022 13:22:00 +0100 Subject: [PATCH 228/401] gfs2: Check sb_bsize_shift after reading superblock Fuzzers like to scribble over sb_bsize_shift but in reality it's very unlikely that this field would be corrupted on its own. Nevertheless it should be checked to avoid the possibility of messy mount errors due to bad calculations. It's always a fixed value based on the block size so we can just check that it's the expected value. Tested with: mkfs.gfs2 -O -p lock_nolock /dev/vdb for i in 0 -1 64 65 32 33; do gfs2_edit -p sb field sb_bsize_shift $i /dev/vdb mount /dev/vdb /mnt/test && umount /mnt/test done Before this patch we get a withdraw after [ 76.413681] gfs2: fsid=loop0.0: fatal: invalid metadata block [ 76.413681] bh = 19 (type: exp=5, found=4) [ 76.413681] function = gfs2_meta_buffer, file = fs/gfs2/meta_io.c, line = 492 and with UBSAN configured we also get complaints like [ 76.373395] UBSAN: shift-out-of-bounds in fs/gfs2/ops_fstype.c:295:19 [ 76.373815] shift exponent 4294967287 is too large for 64-bit type 'long unsigned int' After the patch, these complaints don't appear, mount fails immediately and we get an explanation in dmesg. Reported-by: syzbot+dcf33a7aae997956fe06@syzkaller.appspotmail.com Signed-off-by: Andrew Price Signed-off-by: Andreas Gruenbacher --- fs/gfs2/ops_fstype.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 236b59ef93b6..c7e2e6238366 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -178,7 +178,10 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent) pr_warn("Invalid block size\n"); return -EINVAL; } - + if (sb->sb_bsize_shift != ffs(sb->sb_bsize) - 1) { + pr_warn("Invalid block size shift\n"); + return -EINVAL; + } return 0; } From 74b1b10e29b1f25e1a081fa82733baea65429d53 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Tue, 30 Aug 2022 13:52:13 -0500 Subject: [PATCH 229/401] gfs2: Register fs after creating workqueues Before this patch, the gfs2 file system was registered prior to creating the three workqueues. In some cases this allowed dlm to send recovery work to a workqueue that did not yet exist because gfs2 was still initializing. This patch changes the order of gfs2's initialization routine so it only registers the file system after the work queues are created. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/main.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 14ae9de76277..afcb32854f14 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -151,14 +151,6 @@ static int __init init_gfs2_fs(void) if (error) goto fail_shrinker; - error = register_filesystem(&gfs2_fs_type); - if (error) - goto fail_fs1; - - error = register_filesystem(&gfs2meta_fs_type); - if (error) - goto fail_fs2; - error = -ENOMEM; gfs_recovery_wq = alloc_workqueue("gfs_recovery", WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); @@ -180,11 +172,23 @@ static int __init init_gfs2_fs(void) goto fail_mempool; gfs2_register_debugfs(); + error = register_filesystem(&gfs2_fs_type); + if (error) + goto fail_fs1; + + error = register_filesystem(&gfs2meta_fs_type); + if (error) + goto fail_fs2; + pr_info("GFS2 installed\n"); return 0; +fail_fs2: + unregister_filesystem(&gfs2_fs_type); +fail_fs1: + mempool_destroy(gfs2_page_pool); fail_mempool: destroy_workqueue(gfs2_freeze_wq); fail_wq3: @@ -192,10 +196,6 @@ fail_wq3: fail_wq2: destroy_workqueue(gfs_recovery_wq); fail_wq1: - unregister_filesystem(&gfs2meta_fs_type); -fail_fs2: - unregister_filesystem(&gfs2_fs_type); -fail_fs1: unregister_shrinker(&gfs2_qd_shrinker); fail_shrinker: kmem_cache_destroy(gfs2_trans_cachep); From 8066cc86b7aaaf6b4b38a81932459c6450440daa Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 5 Sep 2022 11:02:27 +0300 Subject: [PATCH 230/401] PCI: Fix used_buses calculation in pci_scan_child_bus_extend() pci_scan_bridge_extend() returns the subordinate bus number needed to cover all the buses below a bridge. pci_scan_child_bus_extend() computes the number of buses to reserve by comparing that with the current max bus number. Previously it did the subtraction in the wrong order, so 'used_buses' was nonsense. Subtract 'max' from 'cmax' as is done for the similar pci_scan_bridge_extend() call in the following block. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216000 Fixes: 3374c545c27c ("PCI: Account for all bridges on bus when distributing bus numbers") Link: https://lore.kernel.org/r/20220905080232.36087-2-mika.westerberg@linux.intel.com Reported-by: Chris Chiu Tested-by: Chris Chiu Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Reviewed-by: Andy Shevchenko --- drivers/pci/probe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c5286b027f00..4f940dcd102c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2920,8 +2920,8 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, * hotplug bridges too much during the second scan below. */ used_buses++; - if (cmax - max > 1) - used_buses += cmax - max - 1; + if (max - cmax > 1) + used_buses += max - cmax - 1; } /* Scan bridges that need to be reconfigured */ From 49ad31e9d78527045614c534df057cadee487773 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 5 Sep 2022 11:02:28 +0300 Subject: [PATCH 231/401] PCI: Pass available buses even if the bridge is already configured If some part of the PCI topology is already configured (by the boot firmware) but not all, and it includes hotplug bridges, we may need to extend the bus resources of those bridges to accommodate any future hotplugs, in the same way we already do with the normal hotplug case. Pass the available buses to pci_scan_child_bus_extend() even when the bridge in question is already configured so the bus allocation code can use these available buses to extend the possible hotplug bridges below. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216000 Link: https://lore.kernel.org/r/20220905080232.36087-3-mika.westerberg@linux.intel.com Reported-by: Chris Chiu Tested-by: Chris Chiu Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Reviewed-by: Andy Shevchenko --- drivers/pci/probe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 4f940dcd102c..86130926a74f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1297,7 +1297,7 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, if ((secondary || subordinate) && !pcibios_assign_all_busses() && !is_cardbus && !broken) { - unsigned int cmax; + unsigned int cmax, buses; /* * Bus already configured by firmware, process it in the @@ -1322,7 +1322,8 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, child->bridge_ctl = bctl; } - cmax = pci_scan_child_bus(child); + buses = subordinate - secondary; + cmax = pci_scan_child_bus_extend(child, buses); if (cmax > subordinate) pci_warn(dev, "bridge has subordinate %02x but max busn %02x\n", subordinate, cmax); From d1caf229c7587b5c514910fff8dc382e69fdcdf5 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 5 Sep 2022 11:02:29 +0300 Subject: [PATCH 232/401] PCI: Move pci_assign_unassigned_root_bus_resources() We need to be able to call pci_bridge_distribute_available_resources() from this function so move it accordingly to avoid need for forward declaration. No functional impact. Link: https://lore.kernel.org/r/20220905080232.36087-4-mika.westerberg@linux.intel.com Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Reviewed-by: Andy Shevchenko --- drivers/pci/setup-bus.c | 226 ++++++++++++++++++++-------------------- 1 file changed, 113 insertions(+), 113 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 8cb68e6f6ef9..3b981da0fb4e 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1745,119 +1745,6 @@ static enum enable_type pci_realloc_detect(struct pci_bus *bus, } #endif -/* - * First try will not touch PCI bridge res. - * Second and later try will clear small leaf bridge res. - * Will stop till to the max depth if can not find good one. - */ -void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus) -{ - LIST_HEAD(realloc_head); - /* List of resources that want additional resources */ - struct list_head *add_list = NULL; - int tried_times = 0; - enum release_type rel_type = leaf_only; - LIST_HEAD(fail_head); - struct pci_dev_resource *fail_res; - int pci_try_num = 1; - enum enable_type enable_local; - - /* Don't realloc if asked to do so */ - enable_local = pci_realloc_detect(bus, pci_realloc_enable); - if (pci_realloc_enabled(enable_local)) { - int max_depth = pci_bus_get_depth(bus); - - pci_try_num = max_depth + 1; - dev_info(&bus->dev, "max bus depth: %d pci_try_num: %d\n", - max_depth, pci_try_num); - } - -again: - /* - * Last try will use add_list, otherwise will try good to have as must - * have, so can realloc parent bridge resource - */ - if (tried_times + 1 == pci_try_num) - add_list = &realloc_head; - /* - * Depth first, calculate sizes and alignments of all subordinate buses. - */ - __pci_bus_size_bridges(bus, add_list); - - /* Depth last, allocate resources and update the hardware. */ - __pci_bus_assign_resources(bus, add_list, &fail_head); - if (add_list) - BUG_ON(!list_empty(add_list)); - tried_times++; - - /* Any device complain? */ - if (list_empty(&fail_head)) - goto dump; - - if (tried_times >= pci_try_num) { - if (enable_local == undefined) - dev_info(&bus->dev, "Some PCI device resources are unassigned, try booting with pci=realloc\n"); - else if (enable_local == auto_enabled) - dev_info(&bus->dev, "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); - - free_list(&fail_head); - goto dump; - } - - dev_info(&bus->dev, "No. %d try to assign unassigned res\n", - tried_times + 1); - - /* Third times and later will not check if it is leaf */ - if ((tried_times + 1) > 2) - rel_type = whole_subtree; - - /* - * Try to release leaf bridge's resources that doesn't fit resource of - * child device under that bridge. - */ - list_for_each_entry(fail_res, &fail_head, list) - pci_bus_release_bridge_resources(fail_res->dev->bus, - fail_res->flags & PCI_RES_TYPE_MASK, - rel_type); - - /* Restore size and flags */ - list_for_each_entry(fail_res, &fail_head, list) { - struct resource *res = fail_res->res; - int idx; - - res->start = fail_res->start; - res->end = fail_res->end; - res->flags = fail_res->flags; - - if (pci_is_bridge(fail_res->dev)) { - idx = res - &fail_res->dev->resource[0]; - if (idx >= PCI_BRIDGE_RESOURCES && - idx <= PCI_BRIDGE_RESOURCE_END) - res->flags = 0; - } - } - free_list(&fail_head); - - goto again; - -dump: - /* Dump the resource on buses */ - pci_bus_dump_resources(bus); -} - -void __init pci_assign_unassigned_resources(void) -{ - struct pci_bus *root_bus; - - list_for_each_entry(root_bus, &pci_root_buses, node) { - pci_assign_unassigned_root_bus_resources(root_bus); - - /* Make sure the root bridge has a companion ACPI device */ - if (ACPI_HANDLE(root_bus->bridge)) - acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge)); - } -} - static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res, struct list_head *add_list, resource_size_t new_size) @@ -2047,6 +1934,119 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge, available_mmio_pref); } +/* + * First try will not touch PCI bridge res. + * Second and later try will clear small leaf bridge res. + * Will stop till to the max depth if can not find good one. + */ +void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus) +{ + LIST_HEAD(realloc_head); + /* List of resources that want additional resources */ + struct list_head *add_list = NULL; + int tried_times = 0; + enum release_type rel_type = leaf_only; + LIST_HEAD(fail_head); + struct pci_dev_resource *fail_res; + int pci_try_num = 1; + enum enable_type enable_local; + + /* Don't realloc if asked to do so */ + enable_local = pci_realloc_detect(bus, pci_realloc_enable); + if (pci_realloc_enabled(enable_local)) { + int max_depth = pci_bus_get_depth(bus); + + pci_try_num = max_depth + 1; + dev_info(&bus->dev, "max bus depth: %d pci_try_num: %d\n", + max_depth, pci_try_num); + } + +again: + /* + * Last try will use add_list, otherwise will try good to have as must + * have, so can realloc parent bridge resource + */ + if (tried_times + 1 == pci_try_num) + add_list = &realloc_head; + /* + * Depth first, calculate sizes and alignments of all subordinate buses. + */ + __pci_bus_size_bridges(bus, add_list); + + /* Depth last, allocate resources and update the hardware. */ + __pci_bus_assign_resources(bus, add_list, &fail_head); + if (add_list) + BUG_ON(!list_empty(add_list)); + tried_times++; + + /* Any device complain? */ + if (list_empty(&fail_head)) + goto dump; + + if (tried_times >= pci_try_num) { + if (enable_local == undefined) + dev_info(&bus->dev, "Some PCI device resources are unassigned, try booting with pci=realloc\n"); + else if (enable_local == auto_enabled) + dev_info(&bus->dev, "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); + + free_list(&fail_head); + goto dump; + } + + dev_info(&bus->dev, "No. %d try to assign unassigned res\n", + tried_times + 1); + + /* Third times and later will not check if it is leaf */ + if ((tried_times + 1) > 2) + rel_type = whole_subtree; + + /* + * Try to release leaf bridge's resources that doesn't fit resource of + * child device under that bridge. + */ + list_for_each_entry(fail_res, &fail_head, list) + pci_bus_release_bridge_resources(fail_res->dev->bus, + fail_res->flags & PCI_RES_TYPE_MASK, + rel_type); + + /* Restore size and flags */ + list_for_each_entry(fail_res, &fail_head, list) { + struct resource *res = fail_res->res; + int idx; + + res->start = fail_res->start; + res->end = fail_res->end; + res->flags = fail_res->flags; + + if (pci_is_bridge(fail_res->dev)) { + idx = res - &fail_res->dev->resource[0]; + if (idx >= PCI_BRIDGE_RESOURCES && + idx <= PCI_BRIDGE_RESOURCE_END) + res->flags = 0; + } + } + free_list(&fail_head); + + goto again; + +dump: + /* Dump the resource on buses */ + pci_bus_dump_resources(bus); +} + +void __init pci_assign_unassigned_resources(void) +{ + struct pci_bus *root_bus; + + list_for_each_entry(root_bus, &pci_root_buses, node) { + pci_assign_unassigned_root_bus_resources(root_bus); + + /* Make sure the root bridge has a companion ACPI device */ + if (ACPI_HANDLE(root_bus->bridge)) + acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge)); + } +} + void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) { struct pci_bus *parent = bridge->subordinate; From e96e27fc6f7971380283768e9a734af16b1716ee Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 5 Sep 2022 11:02:30 +0300 Subject: [PATCH 233/401] PCI: Distribute available resources for root buses, too Previously we distributed spare resources only upon hot-add, so if the initial root bus scan found devices that had not been fully configured by the BIOS, we allocated only enough resources to cover what was then present. If some of those devices were hotplug bridges, we did not leave any additional resource space for future expansion. Distribute the available resources for root buses, too, to make this work the same way as the normal hotplug case. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216000 Link: https://lore.kernel.org/r/20220905080232.36087-5-mika.westerberg@linux.intel.com Reported-by: Chris Chiu Tested-by: Chris Chiu Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Reviewed-by: Andy Shevchenko --- drivers/pci/setup-bus.c | 62 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 3b981da0fb4e..df9fc974b313 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1768,7 +1768,10 @@ static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res, } res->end = res->start + new_size - 1; - remove_from_list(add_list, res); + + /* If the resource is part of the add_list remove it now */ + if (add_list) + remove_from_list(add_list, res); } static void pci_bus_distribute_available_resources(struct pci_bus *bus, @@ -1923,6 +1926,8 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge, if (!bridge->is_hotplug_bridge) return; + pci_dbg(bridge, "distributing available resources\n"); + /* Take the initial extra resources from the hotplug port */ available_io = bridge->resource[PCI_BRIDGE_IO_WINDOW]; available_mmio = bridge->resource[PCI_BRIDGE_MEM_WINDOW]; @@ -1934,6 +1939,59 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge, available_mmio_pref); } +static bool pci_bridge_resources_not_assigned(struct pci_dev *dev) +{ + const struct resource *r; + + /* + * Check the child device's resources and if they are not yet + * assigned it means we are configuring them (not the boot + * firmware) so we should be able to extend the upstream + * bridge's (that's the hotplug downstream PCIe port) resources + * in the same way we do with the normal hotplug case. + */ + r = &dev->resource[PCI_BRIDGE_IO_WINDOW]; + if (!r->flags || !(r->flags & IORESOURCE_STARTALIGN)) + return false; + r = &dev->resource[PCI_BRIDGE_MEM_WINDOW]; + if (!r->flags || !(r->flags & IORESOURCE_STARTALIGN)) + return false; + r = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; + if (!r->flags || !(r->flags & IORESOURCE_STARTALIGN)) + return false; + + return true; +} + +static void pci_root_bus_distribute_available_resources(struct pci_bus *bus, + struct list_head *add_list) +{ + struct pci_dev *dev, *bridge = bus->self; + + for_each_pci_bridge(dev, bus) { + struct pci_bus *b; + + b = dev->subordinate; + if (!b) + continue; + + /* + * Need to check "bridge" here too because it is NULL + * in case of root bus. + */ + if (bridge && pci_bridge_resources_not_assigned(dev)) { + pci_bridge_distribute_available_resources(bridge, add_list); + /* + * There is only PCIe upstream port on the bus + * so we don't need to go futher. + */ + return; + } + + pci_root_bus_distribute_available_resources(b, add_list); + } +} + /* * First try will not touch PCI bridge res. * Second and later try will clear small leaf bridge res. @@ -1973,6 +2031,8 @@ again: */ __pci_bus_size_bridges(bus, add_list); + pci_root_bus_distribute_available_resources(bus, add_list); + /* Depth last, allocate resources and update the hardware. */ __pci_bus_assign_resources(bus, add_list, &fail_head); if (add_list) From 17d2d67d76e41c7fd00608fdad350e1790c5c24a Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 5 Sep 2022 11:02:31 +0300 Subject: [PATCH 234/401] PCI: Fix whitespace and indentation Drop two empty lines from pci_scan_child_bus_extend() and correct indentation in pci_bridge_distribute_available_resources() to better follow the kernel coding style. No functional impact. Link: https://lore.kernel.org/r/20220905080232.36087-6-mika.westerberg@linux.intel.com Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Reviewed-by: Andy Shevchenko --- drivers/pci/probe.c | 2 -- drivers/pci/setup-bus.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 86130926a74f..8f25deb6b763 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2930,7 +2930,6 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, unsigned int buses = 0; if (!hotplug_bridges && normal_bridges == 1) { - /* * There is only one bridge on the bus (upstream * port) so it gets all available buses which it @@ -2939,7 +2938,6 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, */ buses = available_buses; } else if (dev->is_hotplug_bridge) { - /* * Distribute the extra buses between hotplug * bridges if any. diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index df9fc974b313..dc6a30ee6edf 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1919,7 +1919,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, } static void pci_bridge_distribute_available_resources(struct pci_dev *bridge, - struct list_head *add_list) + struct list_head *add_list) { struct resource available_io, available_mmio, available_mmio_pref; From 58e011609c4305fc50674c4610cbe8a8c26261f6 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 5 Sep 2022 11:02:32 +0300 Subject: [PATCH 235/401] PCI: Fix typo in pci_scan_child_bus_extend() Should be 'if' not 'of'. Fix this. Link: https://lore.kernel.org/r/20220905080232.36087-7-mika.westerberg@linux.intel.com Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Reviewed-by: Andy Shevchenko --- drivers/pci/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8f25deb6b763..b66fa42c4b1f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2956,7 +2956,7 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, /* * Make sure a hotplug bridge has at least the minimum requested * number of buses but allow it to grow up to the maximum available - * bus number of there is room. + * bus number if there is room. */ if (bus->self && bus->self->is_hotplug_bridge) { used_buses = max_t(unsigned int, available_buses, From 0e32818397426a688f598f35d3bc762eca6d7592 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 21 Sep 2022 20:49:16 +0100 Subject: [PATCH 236/401] PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge When pci_assign_resource() is unable to assign resources to a BAR, it uses pci_revert_fw_address() to fall back to a firmware assignment (if any). Previously pci_revert_fw_address() assumed all addresses could reach the device, but this is not true if the device is below a bridge that only forwards addresses within its windows. This problem was observed on a Tyan Tomcat IV S1564D system where the BIOS did not assign valid addresses to several bridges and USB devices: pci 0000:00:11.0: PCI-to-PCIe bridge to [bus 01-ff] pci 0000:00:11.0: bridge window [io 0xe000-0xefff] pci 0000:01:00.0: PCIe Upstream Port to [bus 02-ff] pci 0000:01:00.0: bridge window [io 0x0000-0x0fff] # unreachable pci 0000:02:02.0: PCIe Downstream Port to [bus 05-ff] pci 0000:02:02.0: bridge window [io 0x0000-0x0fff] # unreachable pci 0000:05:00.0: PCIe-to-PCI bridge to [bus 06-ff] pci 0000:05:00.0: bridge window [io 0x0000-0x0fff] # unreachable pci 0000:06:08.0: USB UHCI 1.1 pci 0000:06:08.0: BAR 4: [io 0xfce0-0xfcff] # unreachable pci 0000:06:08.1: USB UHCI 1.1 pci 0000:06:08.1: BAR 4: [io 0xfce0-0xfcff] # unreachable pci 0000:06:08.0: can't claim BAR 4 [io 0xfce0-0xfcff]: no compatible bridge window pci 0000:06:08.1: can't claim BAR 4 [io 0xfce0-0xfcff]: no compatible bridge window During the first pass of assigning unassigned resources, there was not enough I/O space available, so we couldn't assign the 06:08.0 BAR and reverted to the firmware assignment (still unreachable). Reverting the 06:08.1 assignment failed because it conflicted with 06:08.0: pci 0000:00:11.0: bridge window [io 0xe000-0xefff] pci 0000:01:00.0: no space for bridge window [io size 0x2000] pci 0000:02:02.0: no space for bridge window [io size 0x1000] pci 0000:05:00.0: no space for bridge window [io size 0x1000] pci 0000:06:08.0: BAR 4: no space for [io size 0x0020] pci 0000:06:08.0: BAR 4: trying firmware assignment [io 0xfce0-0xfcff] pci 0000:06:08.1: BAR 4: no space for [io size 0x0020] pci 0000:06:08.1: BAR 4: trying firmware assignment [io 0xfce0-0xfcff] pci 0000:06:08.1: BAR 4: [io 0xfce0-0xfcff] conflicts with 0000:06:08.0 [io 0xfce0-0xfcff] A subsequent pass assigned valid bridge windows and a valid 06:08.1 BAR, but left the 06:08.0 BAR alone, so the UHCI device was still unusable: pci 0000:00:11.0: bridge window [io 0xe000-0xefff] released pci 0000:00:11.0: bridge window [io 0x1000-0x2fff] # reassigned pci 0000:01:00.0: bridge window [io 0x1000-0x2fff] # reassigned pci 0000:02:02.0: bridge window [io 0x2000-0x2fff] # reassigned pci 0000:05:00.0: bridge window [io 0x2000-0x2fff] # reassigned pci 0000:06:08.0: BAR 4: assigned [io 0xfce0-0xfcff] # left alone pci 0000:06:08.1: BAR 4: assigned [io 0x2000-0x201f] ... uhci_hcd 0000:06:08.0: host system error, PCI problems? uhci_hcd 0000:06:08.0: host controller process error, something bad happened! uhci_hcd 0000:06:08.0: host controller halted, very bad! uhci_hcd 0000:06:08.0: HCRESET not completed yet! uhci_hcd 0000:06:08.0: HC died; cleaning up If the address assigned by firmware is not reachable because it's not within upstream bridge windows, fail instead of assigning the unusable address from firmware. [bhelgaas: commit log, use pci_upstream_bridge()] Link: https://bugzilla.kernel.org/show_bug.cgi?id=16263 Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203012338460.46819@angie.orcam.me.uk Link: https://lore.kernel.org/r/alpine.DEB.2.21.2209211921250.29493@angie.orcam.me.uk Fixes: 58c84eda0756 ("PCI: fall back to original BIOS BAR addresses") Signed-off-by: Maciej W. Rozycki Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # v2.6.35+ --- drivers/pci/setup-res.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 439ac5f5907a..b492e67c3d87 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -214,6 +214,17 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, root = pci_find_parent_resource(dev, res); if (!root) { + /* + * If dev is behind a bridge, accesses will only reach it + * if res is inside the relevant bridge window. + */ + if (pci_upstream_bridge(dev)) + return -ENXIO; + + /* + * On the root bus, assume the host bridge will forward + * everything. + */ if (res->flags & IORESOURCE_IO) root = &ioport_resource; else From ec7174f637d75abe5ada8482b9947898db231cd2 Mon Sep 17 00:00:00 2001 From: Xiu Jianfeng Date: Thu, 22 Sep 2022 19:19:24 +0800 Subject: [PATCH 237/401] ipmi: Add __init/__exit annotations to module init/exit funcs Add missing __init/__exit annotations to module init/exit funcs. Signed-off-by: Xiu Jianfeng Message-Id: <20220922111924.36044-1-xiujianfeng@huawei.com> Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_ssif.c | 4 ++-- drivers/char/ipmi/kcs_bmc_cdev_ipmi.c | 4 ++-- drivers/char/ipmi/kcs_bmc_serio.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index fc742ee9c046..00e9439db0a4 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -2100,7 +2100,7 @@ static struct platform_driver ipmi_driver = { .id_table = ssif_plat_ids }; -static int init_ipmi_ssif(void) +static int __init init_ipmi_ssif(void) { int i; int rv; @@ -2142,7 +2142,7 @@ static int init_ipmi_ssif(void) } module_init(init_ipmi_ssif); -static void cleanup_ipmi_ssif(void) +static void __exit cleanup_ipmi_ssif(void) { if (!initialized) return; diff --git a/drivers/char/ipmi/kcs_bmc_cdev_ipmi.c b/drivers/char/ipmi/kcs_bmc_cdev_ipmi.c index 486834a962c3..cf670e891966 100644 --- a/drivers/char/ipmi/kcs_bmc_cdev_ipmi.c +++ b/drivers/char/ipmi/kcs_bmc_cdev_ipmi.c @@ -548,7 +548,7 @@ static struct kcs_bmc_driver kcs_bmc_ipmi_driver = { .ops = &kcs_bmc_ipmi_driver_ops, }; -static int kcs_bmc_ipmi_init(void) +static int __init kcs_bmc_ipmi_init(void) { kcs_bmc_register_driver(&kcs_bmc_ipmi_driver); @@ -556,7 +556,7 @@ static int kcs_bmc_ipmi_init(void) } module_init(kcs_bmc_ipmi_init); -static void kcs_bmc_ipmi_exit(void) +static void __exit kcs_bmc_ipmi_exit(void) { kcs_bmc_unregister_driver(&kcs_bmc_ipmi_driver); } diff --git a/drivers/char/ipmi/kcs_bmc_serio.c b/drivers/char/ipmi/kcs_bmc_serio.c index 7e2067628a6c..1793358be782 100644 --- a/drivers/char/ipmi/kcs_bmc_serio.c +++ b/drivers/char/ipmi/kcs_bmc_serio.c @@ -140,7 +140,7 @@ static struct kcs_bmc_driver kcs_bmc_serio_driver = { .ops = &kcs_bmc_serio_driver_ops, }; -static int kcs_bmc_serio_init(void) +static int __init kcs_bmc_serio_init(void) { kcs_bmc_register_driver(&kcs_bmc_serio_driver); @@ -148,7 +148,7 @@ static int kcs_bmc_serio_init(void) } module_init(kcs_bmc_serio_init); -static void kcs_bmc_serio_exit(void) +static void __exit kcs_bmc_serio_exit(void) { kcs_bmc_unregister_driver(&kcs_bmc_serio_driver); } From 6f65540b22afaa9c3d621bfb8b2a2958fedf6179 Mon Sep 17 00:00:00 2001 From: Chia-Wei Wang Date: Tue, 20 Sep 2022 10:03:33 +0800 Subject: [PATCH 238/401] ipmi: kcs: aspeed: Update port address comments Remove AST_usrGuide_KCS.pdf as it is no longer maintained. Add more descriptions as the driver now supports the I/O address configurations for both the KCS Data and Cmd/Status interface registers. Signed-off-by: Chia-Wei Wang Message-Id: <20220920020333.601-1-chiawei_wang@aspeedtech.com> [I don't like removing documentation, but the document in question was a personal note by an employee and nothing official and not necessarily guaranteed to be accurate in the future. So go ahead and remove it.] Signed-off-by: Corey Minyard --- drivers/char/ipmi/kcs_bmc_aspeed.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c index cdc88cde1e9a..19c32bf50e0e 100644 --- a/drivers/char/ipmi/kcs_bmc_aspeed.c +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -207,17 +207,24 @@ static void aspeed_kcs_updateb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 mask, } /* - * AST_usrGuide_KCS.pdf - * 2. Background: - * we note D for Data, and C for Cmd/Status, default rules are - * A. KCS1 / KCS2 ( D / C:X / X+4 ) - * D / C : CA0h / CA4h - * D / C : CA8h / CACh - * B. KCS3 ( D / C:XX2h / XX3h ) - * D / C : CA2h / CA3h - * D / C : CB2h / CB3h - * C. KCS4 - * D / C : CA4h / CA5h + * We note D for Data, and C for Cmd/Status, default rules are + * + * 1. Only the D address is given: + * A. KCS1/KCS2 (D/C: X/X+4) + * D/C: CA0h/CA4h + * D/C: CA8h/CACh + * B. KCS3 (D/C: XX2/XX3h) + * D/C: CA2h/CA3h + * C. KCS4 (D/C: X/X+1) + * D/C: CA4h/CA5h + * + * 2. Both the D/C addresses are given: + * A. KCS1/KCS2/KCS4 (D/C: X/Y) + * D/C: CA0h/CA1h + * D/C: CA8h/CA9h + * D/C: CA4h/CA5h + * B. KCS3 (D/C: XX2/XX3h) + * D/C: CA2h/CA3h */ static int aspeed_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u32 addrs[2], int nr_addrs) { From 13a0ac816d22aa47d6c393f14a99f39e49b960df Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 23 Sep 2022 14:53:14 +0200 Subject: [PATCH 239/401] firmware: dmi: Fortify entry point length checks Ensure that the SMBIOS entry point is long enough to include all the fields we need. Otherwise it is pointless to even attempt to verify its checksum. Also fix the maximum length check, which is technically 32, not 31. It does not matter in practice as the only valid values are 31 (for SMBIOS 2.x) and 24 (for SMBIOS 3.x), but let's still have the check right in case new fields are added to either structure in the future. Signed-off-by: Jean Delvare Reported-by: Linus Torvalds Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/lkml/20220823094857.27f3d924@endymion.delvare/T/ --- drivers/firmware/dmi_scan.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 0eb6b617f709..015c95a825d3 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -567,8 +567,13 @@ static int __init dmi_present(const u8 *buf) { u32 smbios_ver; + /* + * The size of this structure is 31 bytes, but we also accept value + * 30 due to a mistake in SMBIOS specification version 2.1. + */ if (memcmp(buf, "_SM_", 4) == 0 && - buf[5] < 32 && dmi_checksum(buf, buf[5])) { + buf[5] >= 30 && buf[5] <= 32 && + dmi_checksum(buf, buf[5])) { smbios_ver = get_unaligned_be16(buf + 6); smbios_entry_point_size = buf[5]; memcpy(smbios_entry_point, buf, smbios_entry_point_size); @@ -629,7 +634,8 @@ static int __init dmi_present(const u8 *buf) static int __init dmi_smbios3_present(const u8 *buf) { if (memcmp(buf, "_SM3_", 5) == 0 && - buf[6] < 32 && dmi_checksum(buf, buf[6])) { + buf[6] >= 24 && buf[6] <= 32 && + dmi_checksum(buf, buf[6])) { dmi_ver = get_unaligned_be24(buf + 7); dmi_num = 0; /* No longer specified */ dmi_len = get_unaligned_le32(buf + 12); From 1a8339c6bdcf7d66a83152ee5ff13c50da761295 Mon Sep 17 00:00:00 2001 From: Yunlong Jia Date: Fri, 23 Sep 2022 09:35:48 -0700 Subject: [PATCH 240/401] dt-bindings: input: touchscreen: elants_i2c: Add compatible for eth3915n chip This adds a new compatible string for Elan eth3915n touchscreen controller, which is compatible with ekth3500. Signed-off-by: Yunlong Jia Suggested-by: Douglas Anderson Reviewed-by: Krzysztof Kozlowski Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20220923083657.v5.2.Ic4e8f03868f88b8027a81bc3d414bae68978e6b7@changeid Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/elan,elants_i2c.yaml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml b/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml index a9b53c2e6f0a..f9053e5e9b24 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml @@ -14,9 +14,13 @@ allOf: properties: compatible: - enum: - - elan,ektf3624 - - elan,ekth3500 + oneOf: + - enum: + - elan,ektf3624 + - elan,ekth3500 + - items: + - const: elan,ekth3915 + - const: elan,ekth3500 reg: maxItems: 1 From 7aacc42f8d7d3bc9efde159b534d9199d9e2cc87 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 23 Sep 2022 21:46:31 +0300 Subject: [PATCH 241/401] Input: matrix_keypad - add missed header inclusion The gpiod_count() API is defined in gpio/consumer.h. Include it. Fixes: f8f7f47d576f ("Input: matrix_keypad - replace of_gpio_named_count() by gpiod_count()") Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220923184632.2157-1-andriy.shevchenko@linux.intel.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/matrix_keypad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 63f078f2bc4a..7dd3f3eda834 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include From 28f677e9d15181556c1f2103d93b9cc093e7b91f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:00 +0200 Subject: [PATCH 242/401] Input: synaptics-rmi4 - fix firmware update operations with bootloader v8 Commit a6977d758fed ("Input: synaptics-rmi4 - support bootloader v8 in f34v7") allowed the F34v7 driver to probe with bootloader v8, but it did not update various other bootloader version checks in the F34 code. Fixes: a6977d758fed ("Input: synaptics-rmi4 - support bootloader v8 in f34v7") Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-2-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c index e5dca9868f87..3afc94f679ed 100644 --- a/drivers/input/rmi4/rmi_f34.c +++ b/drivers/input/rmi4/rmi_f34.c @@ -370,7 +370,7 @@ static int rmi_firmware_update(struct rmi_driver_data *data, f34 = dev_get_drvdata(&data->f34_container->dev); - if (f34->bl_version == 7) { + if (f34->bl_version >= 7) { if (data->pdt_props & HAS_BSR) { dev_err(dev, "%s: LTS not supported\n", __func__); return -ENODEV; @@ -382,7 +382,7 @@ static int rmi_firmware_update(struct rmi_driver_data *data, } /* Enter flash mode */ - if (f34->bl_version == 7) + if (f34->bl_version >= 7) ret = rmi_f34v7_start_reflash(f34, fw); else ret = rmi_f34_enable_flash(f34); @@ -413,7 +413,7 @@ static int rmi_firmware_update(struct rmi_driver_data *data, f34 = dev_get_drvdata(&data->f34_container->dev); /* Perform firmware update */ - if (f34->bl_version == 7) + if (f34->bl_version >= 7) ret = rmi_f34v7_do_reflash(f34, fw); else ret = rmi_f34_update_firmware(f34, fw); From 33fe4d976ff2c1fb6caf961b2e7bbfa66b8a9bf6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:01 +0200 Subject: [PATCH 243/401] Input: synaptics-rmi4 - introduce rmi_f34v7_check_command_status() helper Add a function that waits for the last command to complete and checks the status, and use it where appropriate. This prepares for the subsequent fix of the completion condition in rmi_f34_attention(), which would previously lead to a timeout instead of a more detailed error message whenever a command was unsuccessful with v7/v8 bootloaders. Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-3-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34v7.c | 36 +++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index 8d7ec9d89b18..9049acb3a994 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -72,6 +72,24 @@ static int rmi_f34v7_wait_for_idle(struct f34_data *f34, int timeout_ms) return 0; } +static int rmi_f34v7_check_command_status(struct f34_data *f34, int timeout_ms) +{ + int ret; + + ret = rmi_f34v7_wait_for_idle(f34, timeout_ms); + if (ret < 0) + return ret; + + ret = rmi_f34v7_read_flash_status(f34); + if (ret < 0) + return ret; + + if (f34->v7.flash_status != 0x00) + return -EIO; + + return 0; +} + static int rmi_f34v7_write_command_single_transaction(struct f34_data *f34, u8 cmd) { @@ -318,6 +336,10 @@ static int rmi_f34v7_read_partition_table(struct f34_data *f34) return ret; } + /* + * rmi_f34v7_check_command_status() can't be used here, as this + * function is called before IRQs are available + */ timeout = msecs_to_jiffies(F34_WRITE_WAIT_MS); while (time_before(jiffies, timeout)) { usleep_range(5000, 6000); @@ -674,7 +696,7 @@ static int rmi_f34v7_erase_config(struct f34_data *f34) break; } - ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS); + ret = rmi_f34v7_check_command_status(f34, F34_ERASE_WAIT_MS); if (ret < 0) return ret; @@ -693,7 +715,7 @@ static int rmi_f34v7_erase_guest_code(struct f34_data *f34) if (ret < 0) return ret; - ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS); + ret = rmi_f34v7_check_command_status(f34, F34_ERASE_WAIT_MS); if (ret < 0) return ret; @@ -712,7 +734,7 @@ static int rmi_f34v7_erase_all(struct f34_data *f34) if (ret < 0) return ret; - ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS); + ret = rmi_f34v7_check_command_status(f34, F34_ERASE_WAIT_MS); if (ret < 0) return ret; @@ -787,7 +809,7 @@ static int rmi_f34v7_read_blocks(struct f34_data *f34, if (ret < 0) return ret; - ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS); + ret = rmi_f34v7_check_command_status(f34, F34_ENABLE_WAIT_MS); if (ret < 0) return ret; @@ -871,7 +893,7 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34, return ret; } - ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS); + ret = rmi_f34v7_check_command_status(f34, F34_ENABLE_WAIT_MS); if (ret < 0) return ret; @@ -944,7 +966,7 @@ static int rmi_f34v7_write_flash_config(struct f34_data *f34) rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: Erase flash config command written\n", __func__); - ret = rmi_f34v7_wait_for_idle(f34, F34_WRITE_WAIT_MS); + ret = rmi_f34v7_check_command_status(f34, F34_WRITE_WAIT_MS); if (ret < 0) return ret; @@ -1297,7 +1319,7 @@ static int rmi_f34v7_enter_flash_prog(struct f34_data *f34) if (ret < 0) return ret; - ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS); + ret = rmi_f34v7_check_command_status(f34, F34_ENABLE_WAIT_MS); if (ret < 0) return ret; From b4d6c6a07faa5c860421182d7599f12acfc7dfd0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:02 +0200 Subject: [PATCH 244/401] Input: synaptics-rmi4 - fix command completion check for bootloader v7/v8 The command register is reset to 0 when a command has completed. Check for this condition instead of the error status, which will not accurately reflect completion. In particular, the incorrect condition caused every command error to be reported as a timeout. Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-4-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c index 3afc94f679ed..b811706fb77b 100644 --- a/drivers/input/rmi4/rmi_f34.c +++ b/drivers/input/rmi4/rmi_f34.c @@ -114,13 +114,13 @@ static irqreturn_t rmi_f34_attention(int irq, void *ctx) complete(&f34->v5.cmd_done); } else { ret = rmi_read_block(f34->fn->rmi_dev, - f34->fn->fd.data_base_addr + - f34->v7.off.flash_status, - &status, sizeof(status)); - rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n", + f34->fn->fd.data_base_addr + + f34->v7.off.flash_cmd, + &status, sizeof(status)); + rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: cmd: %#02x, ret: %d\n", __func__, status, ret); - if (!ret && !(status & 0x1f)) + if (!ret && status == CMD_V7_IDLE) complete(&f34->v7.cmd_done); } From 0113b49bd9634ea96cb1237a35308d41f72175af Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:03 +0200 Subject: [PATCH 245/401] Input: synaptics-rmi4 - rewrite partition table unconditionally Preparation for use of the "erase application" command, which is required to recover from a bad partition table error condition. Rather than adding complex fallback error paths for such errors, it seems more robust to do the full erase unconditionally. Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-5-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34.h | 2 - drivers/input/rmi4/rmi_f34v7.c | 153 +++------------------------------ 2 files changed, 13 insertions(+), 142 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34.h b/drivers/input/rmi4/rmi_f34.h index 99faa8c2269d..9495c8542824 100644 --- a/drivers/input/rmi4/rmi_f34.h +++ b/drivers/input/rmi4/rmi_f34.h @@ -262,7 +262,6 @@ struct f34v5_data { struct f34v7_data { bool has_display_cfg; bool has_guest_code; - bool force_update; bool in_bl_mode; u8 *read_config_buf; size_t read_config_buf_size; @@ -276,7 +275,6 @@ struct f34v7_data { u16 payload_length; u8 partitions; u16 partition_table_bytes; - bool new_partition_table; struct register_offset off; struct block_count blkcount; diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index 9049acb3a994..19b94b1c1a33 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -593,68 +593,6 @@ static int rmi_f34v7_read_queries(struct f34_data *f34) return 0; } -static int rmi_f34v7_check_ui_firmware_size(struct f34_data *f34) -{ - u16 block_count; - - block_count = f34->v7.img.ui_firmware.size / f34->v7.block_size; - f34->update_size += block_count; - - if (block_count != f34->v7.blkcount.ui_firmware) { - dev_err(&f34->fn->dev, - "UI firmware size mismatch: %d != %d\n", - block_count, f34->v7.blkcount.ui_firmware); - return -EINVAL; - } - - return 0; -} - -static int rmi_f34v7_check_ui_config_size(struct f34_data *f34) -{ - u16 block_count; - - block_count = f34->v7.img.ui_config.size / f34->v7.block_size; - f34->update_size += block_count; - - if (block_count != f34->v7.blkcount.ui_config) { - dev_err(&f34->fn->dev, "UI config size mismatch\n"); - return -EINVAL; - } - - return 0; -} - -static int rmi_f34v7_check_dp_config_size(struct f34_data *f34) -{ - u16 block_count; - - block_count = f34->v7.img.dp_config.size / f34->v7.block_size; - f34->update_size += block_count; - - if (block_count != f34->v7.blkcount.dp_config) { - dev_err(&f34->fn->dev, "Display config size mismatch\n"); - return -EINVAL; - } - - return 0; -} - -static int rmi_f34v7_check_guest_code_size(struct f34_data *f34) -{ - u16 block_count; - - block_count = f34->v7.img.guest_code.size / f34->v7.block_size; - f34->update_size += block_count; - - if (block_count != f34->v7.blkcount.guest_code) { - dev_err(&f34->fn->dev, "Guest code size mismatch\n"); - return -EINVAL; - } - - return 0; -} - static int rmi_f34v7_check_bl_config_size(struct f34_data *f34) { u16 block_count; @@ -750,7 +688,7 @@ static int rmi_f34v7_erase_all(struct f34_data *f34) return ret; } - if (f34->v7.new_partition_table && f34->v7.has_guest_code) { + if (f34->v7.has_guest_code) { ret = rmi_f34v7_erase_guest_code(f34); if (ret < 0) return ret; @@ -1029,33 +967,6 @@ static int rmi_f34v7_write_firmware(struct f34_data *f34) blk_count, v7_CMD_WRITE_FW); } -static void rmi_f34v7_compare_partition_tables(struct f34_data *f34) -{ - if (f34->v7.phyaddr.ui_firmware != f34->v7.img.phyaddr.ui_firmware) { - f34->v7.new_partition_table = true; - return; - } - - if (f34->v7.phyaddr.ui_config != f34->v7.img.phyaddr.ui_config) { - f34->v7.new_partition_table = true; - return; - } - - if (f34->v7.has_display_cfg && - f34->v7.phyaddr.dp_config != f34->v7.img.phyaddr.dp_config) { - f34->v7.new_partition_table = true; - return; - } - - if (f34->v7.has_guest_code && - f34->v7.phyaddr.guest_code != f34->v7.img.phyaddr.guest_code) { - f34->v7.new_partition_table = true; - return; - } - - f34->v7.new_partition_table = false; -} - static void rmi_f34v7_parse_img_header_10_bl_container(struct f34_data *f34, const void *image) { @@ -1202,8 +1113,6 @@ static int rmi_f34v7_parse_image_info(struct f34_data *f34) rmi_f34v7_parse_partition_table(f34, f34->v7.img.fl_config.data, &f34->v7.img.blkcount, &f34->v7.img.phyaddr); - rmi_f34v7_compare_partition_tables(f34); - return 0; } @@ -1224,44 +1133,18 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw) if (ret < 0) goto fail; - if (!f34->v7.new_partition_table) { - ret = rmi_f34v7_check_ui_firmware_size(f34); - if (ret < 0) - goto fail; - - ret = rmi_f34v7_check_ui_config_size(f34); - if (ret < 0) - goto fail; - - if (f34->v7.has_display_cfg && - f34->v7.img.contains_display_cfg) { - ret = rmi_f34v7_check_dp_config_size(f34); - if (ret < 0) - goto fail; - } - - if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) { - ret = rmi_f34v7_check_guest_code_size(f34); - if (ret < 0) - goto fail; - } - } else { - ret = rmi_f34v7_check_bl_config_size(f34); - if (ret < 0) - goto fail; - } + ret = rmi_f34v7_check_bl_config_size(f34); + if (ret < 0) + goto fail; ret = rmi_f34v7_erase_all(f34); if (ret < 0) goto fail; - if (f34->v7.new_partition_table) { - ret = rmi_f34v7_write_partition_table(f34); - if (ret < 0) - goto fail; - dev_info(&f34->fn->dev, "%s: Partition table programmed\n", - __func__); - } + ret = rmi_f34v7_write_partition_table(f34); + if (ret < 0) + goto fail; + dev_info(&f34->fn->dev, "%s: Partition table programmed\n", __func__); dev_info(&f34->fn->dev, "Writing firmware (%d bytes)...\n", f34->v7.img.ui_firmware.size); @@ -1286,14 +1169,12 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw) goto fail; } - if (f34->v7.new_partition_table) { - if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) { - dev_info(&f34->fn->dev, "Writing guest code...\n"); + if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) { + dev_info(&f34->fn->dev, "Writing guest code...\n"); - ret = rmi_f34v7_write_guest_code(f34); - if (ret < 0) - goto fail; - } + ret = rmi_f34v7_write_guest_code(f34); + if (ret < 0) + goto fail; } fail: @@ -1339,13 +1220,6 @@ int rmi_f34v7_start_reflash(struct f34_data *f34, const struct firmware *fw) if (ret < 0) goto exit; - if (!f34->v7.force_update && f34->v7.new_partition_table) { - dev_err(&f34->fn->dev, "%s: Partition table mismatch\n", - __func__); - ret = -EINVAL; - goto exit; - } - dev_info(&f34->fn->dev, "Firmware image OK\n"); ret = rmi_f34v7_read_flash_status(f34); @@ -1406,6 +1280,5 @@ int rmi_f34v7_probe(struct f34_data *f34) if (ret < 0) return ret; - f34->v7.force_update = true; return 0; } From d316e709cd7e3a84fa6a9b93d0c25754c0cb707e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:04 +0200 Subject: [PATCH 246/401] Input: synaptics-rmi4 - reset after writing partition table When recovering from a bad partition table (for example after an interrupted update), a reset is necessary for the new partition table to become effective. Without this reset, writing the core code partition will fail with status 0x03 (Invalid Command). Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-6-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34v7.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index 19b94b1c1a33..9b78f98bb21c 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -1146,6 +1146,14 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw) goto fail; dev_info(&f34->fn->dev, "%s: Partition table programmed\n", __func__); + /* + * Reset to reload partition table - as the previous firmware has been + * erased, we remain in bootloader mode. + */ + ret = rmi_scan_pdt(f34->fn->rmi_dev, NULL, rmi_initial_reset); + if (ret < 0) + dev_warn(&f34->fn->dev, "RMI reset failed!\n"); + dev_info(&f34->fn->dev, "Writing firmware (%d bytes)...\n", f34->v7.img.ui_firmware.size); From d8d007f25cb6a25b25c0b6447b620638f1febcd3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:05 +0200 Subject: [PATCH 247/401] Input: synaptics-rmi4 - make rmi_f34v7_erase_all() use the "erase all" command A full erase is required to recover from error conditions like "Bad Partition Table". Various individual partition erase commands can be (and need to be) omitted, as they will fail until a new partition table has been written. Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-7-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34v7.c | 87 +--------------------------------- 1 file changed, 1 insertion(+), 86 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index 9b78f98bb21c..9c1a73611761 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -608,58 +608,6 @@ static int rmi_f34v7_check_bl_config_size(struct f34_data *f34) return 0; } -static int rmi_f34v7_erase_config(struct f34_data *f34) -{ - int ret; - - dev_info(&f34->fn->dev, "Erasing config...\n"); - - init_completion(&f34->v7.cmd_done); - - switch (f34->v7.config_area) { - case v7_UI_CONFIG_AREA: - ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_CONFIG); - if (ret < 0) - return ret; - break; - case v7_DP_CONFIG_AREA: - ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_DISP_CONFIG); - if (ret < 0) - return ret; - break; - case v7_BL_CONFIG_AREA: - ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_BL_CONFIG); - if (ret < 0) - return ret; - break; - } - - ret = rmi_f34v7_check_command_status(f34, F34_ERASE_WAIT_MS); - if (ret < 0) - return ret; - - return 0; -} - -static int rmi_f34v7_erase_guest_code(struct f34_data *f34) -{ - int ret; - - dev_info(&f34->fn->dev, "Erasing guest code...\n"); - - init_completion(&f34->v7.cmd_done); - - ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_GUEST_CODE); - if (ret < 0) - return ret; - - ret = rmi_f34v7_check_command_status(f34, F34_ERASE_WAIT_MS); - if (ret < 0) - return ret; - - return 0; -} - static int rmi_f34v7_erase_all(struct f34_data *f34) { int ret; @@ -668,7 +616,7 @@ static int rmi_f34v7_erase_all(struct f34_data *f34) init_completion(&f34->v7.cmd_done); - ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_FIRMWARE); + ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_ALL); if (ret < 0) return ret; @@ -676,24 +624,6 @@ static int rmi_f34v7_erase_all(struct f34_data *f34) if (ret < 0) return ret; - f34->v7.config_area = v7_UI_CONFIG_AREA; - ret = rmi_f34v7_erase_config(f34); - if (ret < 0) - return ret; - - if (f34->v7.has_display_cfg) { - f34->v7.config_area = v7_DP_CONFIG_AREA; - ret = rmi_f34v7_erase_config(f34); - if (ret < 0) - return ret; - } - - if (f34->v7.has_guest_code) { - ret = rmi_f34v7_erase_guest_code(f34); - if (ret < 0) - return ret; - } - return 0; } @@ -897,17 +827,6 @@ static int rmi_f34v7_write_flash_config(struct f34_data *f34) init_completion(&f34->v7.cmd_done); - ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_FLASH_CONFIG); - if (ret < 0) - return ret; - - rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, - "%s: Erase flash config command written\n", __func__); - - ret = rmi_f34v7_check_command_status(f34, F34_WRITE_WAIT_MS); - if (ret < 0) - return ret; - ret = rmi_f34v7_write_config(f34); if (ret < 0) return ret; @@ -937,10 +856,6 @@ static int rmi_f34v7_write_partition_table(struct f34_data *f34) if (ret < 0) return ret; - ret = rmi_f34v7_erase_config(f34); - if (ret < 0) - return ret; - ret = rmi_f34v7_write_flash_config(f34); if (ret < 0) return ret; From b077d523d4d91e7239864997ffe2a30ac30055c1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:06 +0200 Subject: [PATCH 248/401] Input: synaptics-rmi4 - remove unneeded struct register_offset All register offsets are fixed, and a number of places even read or write multiple registers as a block, so there is no way to support reordering them without move involved changes. Remove the unneeded level of indirection in the register access. Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-8-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34.c | 2 +- drivers/input/rmi4/rmi_f34.h | 15 --------------- drivers/input/rmi4/rmi_f34v7.c | 35 ++++++++++++++-------------------- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c index b811706fb77b..30169b584573 100644 --- a/drivers/input/rmi4/rmi_f34.c +++ b/drivers/input/rmi4/rmi_f34.c @@ -115,7 +115,7 @@ static irqreturn_t rmi_f34_attention(int irq, void *ctx) } else { ret = rmi_read_block(f34->fn->rmi_dev, f34->fn->fd.data_base_addr + - f34->v7.off.flash_cmd, + V7_COMMAND_OFFSET, &status, sizeof(status)); rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: cmd: %#02x, ret: %d\n", __func__, status, ret); diff --git a/drivers/input/rmi4/rmi_f34.h b/drivers/input/rmi4/rmi_f34.h index 9495c8542824..cfa3039804fd 100644 --- a/drivers/input/rmi4/rmi_f34.h +++ b/drivers/input/rmi4/rmi_f34.h @@ -222,20 +222,6 @@ struct image_metadata { struct physical_address phyaddr; }; -struct register_offset { - u8 properties; - u8 properties_2; - u8 block_size; - u8 block_count; - u8 gc_block_count; - u8 flash_status; - u8 partition_id; - u8 block_number; - u8 transfer_length; - u8 flash_cmd; - u8 payload; -}; - struct rmi_f34_firmware { __le32 checksum; u8 pad1[3]; @@ -276,7 +262,6 @@ struct f34v7_data { u8 partitions; u16 partition_table_bytes; - struct register_offset off; struct block_count blkcount; struct physical_address phyaddr; struct image_metadata img; diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index 9c1a73611761..5c22ad4bcc74 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -25,7 +25,7 @@ static int rmi_f34v7_read_flash_status(struct f34_data *f34) int ret; ret = rmi_read_block(f34->fn->rmi_dev, - f34->fn->fd.data_base_addr + f34->v7.off.flash_status, + f34->fn->fd.data_base_addr + V7_FLASH_STATUS_OFFSET, &status, sizeof(status)); if (ret < 0) { @@ -43,7 +43,7 @@ static int rmi_f34v7_read_flash_status(struct f34_data *f34) } ret = rmi_read_block(f34->fn->rmi_dev, - f34->fn->fd.data_base_addr + f34->v7.off.flash_cmd, + f34->fn->fd.data_base_addr + V7_COMMAND_OFFSET, &command, sizeof(command)); if (ret < 0) { @@ -140,7 +140,7 @@ static int rmi_f34v7_write_command_single_transaction(struct f34_data *f34, data_1_5.payload[1] = f34->bootloader_id[1]; ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.partition_id, + base + V7_PARTITION_ID_OFFSET, &data_1_5, sizeof(data_1_5)); if (ret < 0) { dev_err(&f34->fn->dev, @@ -213,7 +213,7 @@ static int rmi_f34v7_write_command(struct f34_data *f34, u8 cmd) __func__, command); ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.flash_cmd, + base + V7_COMMAND_OFFSET, &command, sizeof(command)); if (ret < 0) { dev_err(&f34->fn->dev, "%s: Failed to write flash command\n", @@ -280,7 +280,7 @@ static int rmi_f34v7_write_partition_id(struct f34_data *f34, u8 cmd) } ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.partition_id, + base + V7_PARTITION_ID_OFFSET, &partition, sizeof(partition)); if (ret < 0) { dev_err(&f34->fn->dev, "%s: Failed to write partition ID\n", @@ -308,7 +308,7 @@ static int rmi_f34v7_read_partition_table(struct f34_data *f34) return ret; ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.block_number, + base + V7_BLOCK_NUMBER_OFFSET, &block_number, sizeof(block_number)); if (ret < 0) { dev_err(&f34->fn->dev, "%s: Failed to write block number\n", @@ -319,7 +319,7 @@ static int rmi_f34v7_read_partition_table(struct f34_data *f34) put_unaligned_le16(f34->v7.flash_config_length, &length); ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.transfer_length, + base + V7_TRANSFER_LENGTH_OFFSET, &length, sizeof(length)); if (ret < 0) { dev_err(&f34->fn->dev, "%s: Failed to write transfer length\n", @@ -352,7 +352,7 @@ static int rmi_f34v7_read_partition_table(struct f34_data *f34) } ret = rmi_read_block(f34->fn->rmi_dev, - base + f34->v7.off.payload, + base + V7_PAYLOAD_OFFSET, f34->v7.read_config_buf, f34->v7.partition_table_bytes); if (ret < 0) { @@ -526,13 +526,6 @@ static int rmi_f34v7_read_queries(struct f34_data *f34) rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: f34->v7.block_size = %d\n", __func__, f34->v7.block_size); - f34->v7.off.flash_status = V7_FLASH_STATUS_OFFSET; - f34->v7.off.partition_id = V7_PARTITION_ID_OFFSET; - f34->v7.off.block_number = V7_BLOCK_NUMBER_OFFSET; - f34->v7.off.transfer_length = V7_TRANSFER_LENGTH_OFFSET; - f34->v7.off.flash_cmd = V7_COMMAND_OFFSET; - f34->v7.off.payload = V7_PAYLOAD_OFFSET; - f34->v7.has_display_cfg = query_1_7.partition_support[1] & HAS_DISP_CFG; f34->v7.has_guest_code = query_1_7.partition_support[1] & HAS_GUEST_CODE; @@ -646,7 +639,7 @@ static int rmi_f34v7_read_blocks(struct f34_data *f34, return ret; ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.block_number, + base + V7_BLOCK_NUMBER_OFFSET, &block_number, sizeof(block_number)); if (ret < 0) { dev_err(&f34->fn->dev, "%s: Failed to write block number\n", @@ -662,7 +655,7 @@ static int rmi_f34v7_read_blocks(struct f34_data *f34, put_unaligned_le16(transfer, &length); ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.transfer_length, + base + V7_TRANSFER_LENGTH_OFFSET, &length, sizeof(length)); if (ret < 0) { dev_err(&f34->fn->dev, @@ -682,7 +675,7 @@ static int rmi_f34v7_read_blocks(struct f34_data *f34, return ret; ret = rmi_read_block(f34->fn->rmi_dev, - base + f34->v7.off.payload, + base + V7_PAYLOAD_OFFSET, &f34->v7.read_config_buf[index], transfer * f34->v7.block_size); if (ret < 0) { @@ -718,7 +711,7 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34, return ret; ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.block_number, + base + V7_BLOCK_NUMBER_OFFSET, &block_number, sizeof(block_number)); if (ret < 0) { dev_err(&f34->fn->dev, "%s: Failed to write block number\n", @@ -738,7 +731,7 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34, init_completion(&f34->v7.cmd_done); ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.transfer_length, + base + V7_TRANSFER_LENGTH_OFFSET, &length, sizeof(length)); if (ret < 0) { dev_err(&f34->fn->dev, @@ -752,7 +745,7 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34, return ret; ret = rmi_write_block(f34->fn->rmi_dev, - base + f34->v7.off.payload, + base + V7_PAYLOAD_OFFSET, block_ptr, transfer * f34->v7.block_size); if (ret < 0) { dev_err(&f34->fn->dev, From 7d128a8d4107084a1df548d9304b9e49153808b8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:07 +0200 Subject: [PATCH 249/401] Input: synaptics-rmi4 - simplify rmi_f34v7_start_reflash() rmi_f34v7_enter_flash_prog() already enables IRQs and checks the flash status - there's no need for rmi_f34v7_start_reflash() to do the same just before calling rmi_f34v7_enter_flash_prog(). Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-9-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34v7.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index 5c22ad4bcc74..f16c67eb6cc6 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -1107,8 +1107,11 @@ static int rmi_f34v7_enter_flash_prog(struct f34_data *f34) if (ret < 0) return ret; - if (f34->v7.in_bl_mode) + if (f34->v7.in_bl_mode) { + dev_info(&f34->fn->dev, "%s: Device in bootloader mode\n", + __func__); return 0; + } init_completion(&f34->v7.cmd_done); @@ -1127,32 +1130,16 @@ int rmi_f34v7_start_reflash(struct f34_data *f34, const struct firmware *fw) { int ret = 0; - f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev, f34->fn->irq_mask); - f34->v7.config_area = v7_UI_CONFIG_AREA; f34->v7.image = fw->data; ret = rmi_f34v7_parse_image_info(f34); if (ret < 0) - goto exit; + return ret; dev_info(&f34->fn->dev, "Firmware image OK\n"); - ret = rmi_f34v7_read_flash_status(f34); - if (ret < 0) - goto exit; - - if (f34->v7.in_bl_mode) { - dev_info(&f34->fn->dev, "%s: Device in bootloader mode\n", - __func__); - } - - rmi_f34v7_enter_flash_prog(f34); - - return 0; - -exit: - return ret; + return rmi_f34v7_enter_flash_prog(f34); } int rmi_f34v7_probe(struct f34_data *f34) From 87d3d1b1403ba079cf9b1541a247156863af07f0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 8 Jun 2022 14:48:08 +0200 Subject: [PATCH 250/401] Input: synaptics-rmi4 - drop useless gotos in rmi_f34v7_do_reflash() Returning directly makes the code clearer. Signed-off-by: Matthias Schiffer Reviewed-by: Lyude Paul Link: https://lore.kernel.org/r/20220608124808.51402-10-matthias.schiffer@ew.tq-group.com Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34v7.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index f16c67eb6cc6..886557b01eba 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -1039,19 +1039,19 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw) ret = rmi_f34v7_parse_image_info(f34); if (ret < 0) - goto fail; + return ret; ret = rmi_f34v7_check_bl_config_size(f34); if (ret < 0) - goto fail; + return ret; ret = rmi_f34v7_erase_all(f34); if (ret < 0) - goto fail; + return ret; ret = rmi_f34v7_write_partition_table(f34); if (ret < 0) - goto fail; + return ret; dev_info(&f34->fn->dev, "%s: Partition table programmed\n", __func__); /* @@ -1067,7 +1067,7 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw) ret = rmi_f34v7_write_firmware(f34); if (ret < 0) - goto fail; + return ret; dev_info(&f34->fn->dev, "Writing config (%d bytes)...\n", f34->v7.img.ui_config.size); @@ -1075,14 +1075,14 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw) f34->v7.config_area = v7_UI_CONFIG_AREA; ret = rmi_f34v7_write_ui_config(f34); if (ret < 0) - goto fail; + return ret; if (f34->v7.has_display_cfg && f34->v7.img.contains_display_cfg) { dev_info(&f34->fn->dev, "Writing display config...\n"); ret = rmi_f34v7_write_dp_config(f34); if (ret < 0) - goto fail; + return ret; } if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) { @@ -1090,11 +1090,10 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw) ret = rmi_f34v7_write_guest_code(f34); if (ret < 0) - goto fail; + return ret; } -fail: - return ret; + return 0; } static int rmi_f34v7_enter_flash_prog(struct f34_data *f34) From 6dc0a438f91d5ece823261204248670995504139 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Sat, 24 Sep 2022 22:35:30 -0700 Subject: [PATCH 251/401] Input: twl4030-vibra - drop legacy, non DT boot support Legacy or non DT boot is no longer possible on systems where the tw4030/5030 is used. Drop the support for handling legacy pdata. Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20220616153323.29464-1-peter.ujfalusi@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl4030-vibra.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index e0ff616fb857..5619996da86f 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c @@ -163,14 +163,10 @@ static int __maybe_unused twl4030_vibra_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, twl4030_vibra_suspend, twl4030_vibra_resume); -static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata, - struct device_node *parent) +static bool twl4030_vibra_check_coexist(struct device_node *parent) { struct device_node *node; - if (pdata && pdata->coexist) - return true; - node = of_get_child_by_name(parent, "codec"); if (node) { of_node_put(node); @@ -182,13 +178,12 @@ static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata, static int twl4030_vibra_probe(struct platform_device *pdev) { - struct twl4030_vibra_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *twl4030_core_node = pdev->dev.parent->of_node; struct vibra_info *info; int ret; - if (!pdata && !twl4030_core_node) { - dev_dbg(&pdev->dev, "platform_data not available\n"); + if (!twl4030_core_node) { + dev_dbg(&pdev->dev, "twl4030 OF node is missing\n"); return -EINVAL; } @@ -197,7 +192,7 @@ static int twl4030_vibra_probe(struct platform_device *pdev) return -ENOMEM; info->dev = &pdev->dev; - info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node); + info->coexist = twl4030_vibra_check_coexist(twl4030_core_node); INIT_WORK(&info->play_work, vibra_play_work); info->input_dev = devm_input_allocate_device(&pdev->dev); From 4160f9680d7f8bb0f4e4e114869146a694347b89 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sat, 17 Sep 2022 17:57:00 +0200 Subject: [PATCH 252/401] dt-bindings: input: qcom,pm8xxx-vib: convert to yaml Convert the PM8xxx PMIC Vibrator bindings to dt-schema. Signed-off-by: Luca Weiss Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220917155705.2284-1-luca@z3ntu.xyz Signed-off-by: Dmitry Torokhov --- .../bindings/input/qcom,pm8xxx-vib.txt | 23 ----------- .../bindings/input/qcom,pm8xxx-vib.yaml | 38 +++++++++++++++++++ 2 files changed, 38 insertions(+), 23 deletions(-) delete mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.txt create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.yaml diff --git a/Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.txt b/Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.txt deleted file mode 100644 index 64bb990075c3..000000000000 --- a/Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.txt +++ /dev/null @@ -1,23 +0,0 @@ -Qualcomm PM8xxx PMIC Vibrator - -PROPERTIES - -- compatible: - Usage: required - Value type: - Definition: must be one of: - "qcom,pm8058-vib" - "qcom,pm8916-vib" - "qcom,pm8921-vib" - -- reg: - Usage: required - Value type: - Definition: address of vibration control register - -EXAMPLE - - vibrator@4a { - compatible = "qcom,pm8058-vib"; - reg = <0x4a>; - }; diff --git a/Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.yaml b/Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.yaml new file mode 100644 index 000000000000..c8832cd0d7da --- /dev/null +++ b/Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.yaml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/qcom,pm8xxx-vib.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm PM8xxx PMIC Vibrator + +maintainers: + - Bjorn Andersson + +properties: + compatible: + enum: + - qcom,pm8058-vib + - qcom,pm8916-vib + - qcom,pm8921-vib + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pmic { + #address-cells = <1>; + #size-cells = <0>; + + vibrator@4a { + compatible = "qcom,pm8058-vib"; + reg = <0x4a>; + }; + }; From 5db8a0d31cab2798f693a360628dcafaee1ecce9 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Sun, 25 Sep 2022 00:19:11 -0700 Subject: [PATCH 253/401] Input: joydev - fix comment typo The double `from' is duplicated in the comment, remove one. Signed-off-by: Jason Wang Link: https://lore.kernel.org/r/20220804120800.60415-1-wangborong@cdjrlc.com Signed-off-by: Dmitry Torokhov --- drivers/input/joydev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b45ddb457002..5824bca02e5a 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -746,7 +746,7 @@ static void joydev_cleanup(struct joydev *joydev) } /* - * These codes are copied from from hid-ids.h, unfortunately there is no common + * These codes are copied from hid-ids.h, unfortunately there is no common * usb_ids/bt_ids.h header. */ #define USB_VENDOR_ID_SONY 0x054c From c3b6eed31f441129aee1cd8e59fd20ba2842f3c9 Mon Sep 17 00:00:00 2001 From: Jiangshan Yi Date: Tue, 6 Sep 2022 11:24:35 +0800 Subject: [PATCH 254/401] cifs: misc: fix spelling typo in comment Fix spelling typo in comment. Reported-by: k2ci Signed-off-by: Jiangshan Yi Signed-off-by: Steve French --- fs/cifs/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 87f60f736731..c6679398fff9 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -824,7 +824,7 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path) free_dentry_path(page); } -/* parses DFS refferal V3 structure +/* parses DFS referral V3 structure * caller is responsible for freeing target_nodes * returns: * - on success - 0 From d7752a6c60c2de889425e27912e3fa96ba5626b2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 19 Sep 2022 23:08:03 -0500 Subject: [PATCH 255/401] MAINTAINERS: Add Tom Talpey as cifs.ko reviewer He has been actively reviewing and submitting patches, especially for smbdirect (RDMA) so add him as a reviewer for cifs.ko Acked-by: Tom Talpey Signed-off-by: Steve French --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index f5ca4aefd184..77ce0efb84c5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5139,6 +5139,7 @@ M: Steve French R: Paulo Alcantara (DFS, global name space) R: Ronnie Sahlberg (directory leases, sparse files) R: Shyam Prasad N (multichannel) +R: Tom Talpey (RDMA, smbdirect) L: linux-cifs@vger.kernel.org L: samba-technical@lists.samba.org (moderated for non-subscribers) S: Supported From 09a1f9a168ae1f69f701689429871793174417d2 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Fri, 16 Sep 2022 20:57:05 -0300 Subject: [PATCH 256/401] cifs: return correct error in ->calc_signature() If an error happens while getting the key or session in the ->calc_signature implementations, 0 (success) is returned. Fix it by returning a proper error code. Since it seems to be highly unlikely to happen wrap the rc check in unlikely() too. Reviewed-by: Ronnie Sahlberg Fixes: 32811d242ff6 ("cifs: Start using per session key for smb2/3 for signature generation") Signed-off-by: Enzo Matsumiya Signed-off-by: Steve French --- fs/cifs/smb2transport.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index 1a5fc3314dbf..4640fc4a8b13 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -225,9 +225,9 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, struct smb_rqst drqst; ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId)); - if (!ses) { + if (unlikely(!ses)) { cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); - return 0; + return -ENOENT; } memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); @@ -557,8 +557,10 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, u8 key[SMB3_SIGN_KEY_SIZE]; rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key); - if (rc) - return 0; + if (unlikely(rc)) { + cifs_server_dbg(VFS, "%s: Could not get signing key\n", __func__); + return rc; + } if (allocate_crypto) { rc = cifs_alloc_hash("cmac(aes)", &hash, &sdesc); From bb44c31cdcac107344dd2fcc3bd0504a53575c51 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Tue, 20 Sep 2022 14:32:02 +1000 Subject: [PATCH 257/401] cifs: destage dirty pages before re-reading them for cache=none This is the opposite case of kernel bugzilla 216301. If we mmap a file using cache=none and then proceed to update the mmapped area these updates are not reflected in a later pread() of that part of the file. To fix this we must first destage any dirty pages in the range before we allow the pread() to proceed. Cc: stable@vger.kernel.org Reviewed-by: Paulo Alcantara (SUSE) Reviewed-by: Enzo Matsumiya Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/file.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 6f38b134a346..7d756721e1a6 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -4271,6 +4271,15 @@ static ssize_t __cifs_readv( len = ctx->len; } + if (direct) { + rc = filemap_write_and_wait_range(file->f_inode->i_mapping, + offset, offset + len - 1); + if (rc) { + kref_put(&ctx->refcount, cifs_aio_ctx_release); + return -EAGAIN; + } + } + /* grab a lock here due to read response handlers can access ctx */ mutex_lock(&ctx->aio_mutex); From ddc9589d7921d7af4cc8fa6e0477d83fd95adef5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 23 Sep 2022 12:47:34 -0700 Subject: [PATCH 258/401] Input: lm8333 - add missing linux/input.h include We are going to clean up matrix_keymap.h from unnecessary includes, so the driver needs to include API that it uses directly. Also let's sort includes alphabetically and drop unneeded irq.h Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220923194738.927408-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/lm8333.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c index 9dac22c14125..3052cd6dedac 100644 --- a/drivers/input/keyboard/lm8333.c +++ b/drivers/input/keyboard/lm8333.c @@ -4,13 +4,13 @@ * Copyright (C) 2012 Wolfram Sang, Pengutronix */ -#include -#include -#include #include -#include +#include #include #include +#include +#include +#include #define LM8333_FIFO_READ 0x20 #define LM8333_DEBOUNCE 0x22 From d25a9d8f8d314e65a229cc828433ce3cc9cfbd4e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 23 Sep 2022 12:47:35 -0700 Subject: [PATCH 259/401] Input: st-keyscan - add missing linux/input.h and linux/of.h includes We are going to clean up matrix_keymap.h from unnecessary includes, so the driver needs to include API that it uses directly. Also let's sort includes alphabetically. Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220923194738.927408-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/st-keyscan.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c index a045d61165ac..a62bb8fff88c 100644 --- a/drivers/input/keyboard/st-keyscan.c +++ b/drivers/input/keyboard/st-keyscan.c @@ -8,12 +8,14 @@ * Based on sh_keysc.c, copyright 2008 Magnus Damm */ -#include -#include -#include #include -#include +#include #include +#include +#include +#include +#include +#include #define ST_KEYSCAN_MAXKEYS 16 From 81a7cba79d0015fd50eb99ea6f682efce6005d05 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 23 Sep 2022 12:47:36 -0700 Subject: [PATCH 260/401] Input: mt6779-keypad - add missing linux/input.h include We are going to clean up matrix_keymap.h from unnecessary includes, so the driver needs to include API that it uses directly. Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220923194738.927408-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mt6779-keypad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/keyboard/mt6779-keypad.c b/drivers/input/keyboard/mt6779-keypad.c index a05e70af1fd0..19f69d167fbd 100644 --- a/drivers/input/keyboard/mt6779-keypad.c +++ b/drivers/input/keyboard/mt6779-keypad.c @@ -5,6 +5,7 @@ */ #include #include +#include #include #include #include From 4e9cded6192800a7aed8df7290896e0956b54782 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 23 Sep 2022 12:47:37 -0700 Subject: [PATCH 261/401] Input: imx_keypad - add missing linux/input.h include We are going to clean up matrix_keymap.h from unnecessary includes, so the driver needs to include API that it uses directly. Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220923194738.927408-4-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/imx_keypad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index ae9303848571..e15a93619e82 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include From da7a0123ed77dacf6c7bd2c4748bcd39d6bd1b82 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 23 Sep 2022 12:47:38 -0700 Subject: [PATCH 262/401] Input: ep93xx_keypad - add missing linux/input.h include We are going to clean up matrix_keymap.h from unnecessary includes, so the driver needs to include API that it uses directly. Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220923194738.927408-5-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/ep93xx_keypad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index 7a3b0664ab4f..f5bf7524722a 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include From 24613f7c7f2dbd0b47ecdf9928600379e606dfda Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 26 Sep 2022 16:48:21 -0500 Subject: [PATCH 263/401] Input: applespi - replace zero-length array with DECLARE_FLEX_ARRAY() helper Zero-length arrays are deprecated and we are moving towards adopting C99 flexible-array members, instead. So, replace zero-length arrays declarations in anonymous union with the new DECLARE_FLEX_ARRAY() helper macro. This helper allows for flexible-array members in unions. Link: https://github.com/KSPP/linux/issues/193 Link: https://github.com/KSPP/linux/issues/219 Link: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html Signed-off-by: Gustavo A. R. Silva Reviewed-by: Kees Cook Link: https://lore.kernel.org/r/YzIeJeqU73G+UI8g@work Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/applespi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c index fab5473ae5da..91a9810f6980 100644 --- a/drivers/input/keyboard/applespi.c +++ b/drivers/input/keyboard/applespi.c @@ -311,7 +311,7 @@ struct message { struct command_protocol_mt_init init_mt_command; struct command_protocol_capsl capsl_command; struct command_protocol_bl bl_command; - u8 data[0]; + DECLARE_FLEX_ARRAY(u8, data); }; }; From 8a9b7ef74369f08a8bde2a45168056f1cad9fb2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 24 Sep 2022 11:24:02 +0200 Subject: [PATCH 264/401] PCI: Add standard PCI Config Address macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lot of PCI and PCIe controllers are using standard Config Address for PCI Configuration Mechanism #1 (as defined in PCI Local Bus Specification) or its extended version. So introduce new macros PCI_CONF1_ADDRESS() and PCI_CONF1_EXT_ADDRESS() in include file drivers/pci/pci.h which can be suitable for PCI and PCIe controllers which uses this type of access to PCI config space. Link: https://lore.kernel.org/r/20220924092404.31776-2-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Acked-by: Bjorn Helgaas --- drivers/pci/pci.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 785f31086313..88bd77107103 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -774,4 +774,49 @@ static inline pci_power_t mid_pci_get_power_state(struct pci_dev *pdev) } #endif +/* + * Config Address for PCI Configuration Mechanism #1 + * + * See PCI Local Bus Specification, Revision 3.0, + * Section 3.2.2.3.2, Figure 3-2, p. 50. + */ + +#define PCI_CONF1_BUS_SHIFT 16 /* Bus number */ +#define PCI_CONF1_DEV_SHIFT 11 /* Device number */ +#define PCI_CONF1_FUNC_SHIFT 8 /* Function number */ + +#define PCI_CONF1_BUS_MASK 0xff +#define PCI_CONF1_DEV_MASK 0x1f +#define PCI_CONF1_FUNC_MASK 0x7 +#define PCI_CONF1_REG_MASK 0xfc /* Limit aligned offset to a maximum of 256B */ + +#define PCI_CONF1_ENABLE BIT(31) +#define PCI_CONF1_BUS(x) (((x) & PCI_CONF1_BUS_MASK) << PCI_CONF1_BUS_SHIFT) +#define PCI_CONF1_DEV(x) (((x) & PCI_CONF1_DEV_MASK) << PCI_CONF1_DEV_SHIFT) +#define PCI_CONF1_FUNC(x) (((x) & PCI_CONF1_FUNC_MASK) << PCI_CONF1_FUNC_SHIFT) +#define PCI_CONF1_REG(x) ((x) & PCI_CONF1_REG_MASK) + +#define PCI_CONF1_ADDRESS(bus, dev, func, reg) \ + (PCI_CONF1_ENABLE | \ + PCI_CONF1_BUS(bus) | \ + PCI_CONF1_DEV(dev) | \ + PCI_CONF1_FUNC(func) | \ + PCI_CONF1_REG(reg)) + +/* + * Extension of PCI Config Address for accessing extended PCIe registers + * + * No standardized specification, but used on lot of non-ECAM-compliant ARM SoCs + * or on AMD Barcelona and new CPUs. Reserved bits [27:24] of PCI Config Address + * are used for specifying additional 4 high bits of PCI Express register. + */ + +#define PCI_CONF1_EXT_REG_SHIFT 16 +#define PCI_CONF1_EXT_REG_MASK 0xf00 +#define PCI_CONF1_EXT_REG(x) (((x) & PCI_CONF1_EXT_REG_MASK) << PCI_CONF1_EXT_REG_SHIFT) + +#define PCI_CONF1_EXT_ADDRESS(bus, dev, func, reg) \ + (PCI_CONF1_ADDRESS(bus, dev, func, reg) | \ + PCI_CONF1_EXT_REG(reg)) + #endif /* DRIVERS_PCI_H */ From f75a27dc6c07cbf371572cf0539c3b60e7d50c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 24 Sep 2022 11:24:03 +0200 Subject: [PATCH 265/401] PCI: ftpci100: Use PCI_CONF1_ADDRESS() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify pci-ftpci100.c driver code and use new PCI_CONF1_ADDRESS() macro for accessing PCI config space. Link: https://lore.kernel.org/r/20220924092404.31776-3-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/pci-ftpci100.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c index 88980a44461d..0cfd9d5a497c 100644 --- a/drivers/pci/controller/pci-ftpci100.c +++ b/drivers/pci/controller/pci-ftpci100.c @@ -103,13 +103,6 @@ #define FARADAY_PCI_DMA_MEM2_BASE 0x00000000 #define FARADAY_PCI_DMA_MEM3_BASE 0x00000000 -/* Defines for PCI configuration command register */ -#define PCI_CONF_ENABLE BIT(31) -#define PCI_CONF_WHERE(r) ((r) & 0xFC) -#define PCI_CONF_BUS(b) (((b) & 0xFF) << 16) -#define PCI_CONF_DEVICE(d) (((d) & 0x1F) << 11) -#define PCI_CONF_FUNCTION(f) (((f) & 0x07) << 8) - /** * struct faraday_pci_variant - encodes IP block differences * @cascaded_irq: this host has cascaded IRQs from an interrupt controller @@ -190,11 +183,8 @@ static int faraday_raw_pci_read_config(struct faraday_pci *p, int bus_number, unsigned int fn, int config, int size, u32 *value) { - writel(PCI_CONF_BUS(bus_number) | - PCI_CONF_DEVICE(PCI_SLOT(fn)) | - PCI_CONF_FUNCTION(PCI_FUNC(fn)) | - PCI_CONF_WHERE(config) | - PCI_CONF_ENABLE, + writel(PCI_CONF1_ADDRESS(bus_number, PCI_SLOT(fn), + PCI_FUNC(fn), config), p->base + FTPCI_CONFIG); *value = readl(p->base + FTPCI_DATA); @@ -225,11 +215,8 @@ static int faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number, { int ret = PCIBIOS_SUCCESSFUL; - writel(PCI_CONF_BUS(bus_number) | - PCI_CONF_DEVICE(PCI_SLOT(fn)) | - PCI_CONF_FUNCTION(PCI_FUNC(fn)) | - PCI_CONF_WHERE(config) | - PCI_CONF_ENABLE, + writel(PCI_CONF1_ADDRESS(bus_number, PCI_SLOT(fn), + PCI_FUNC(fn), config), p->base + FTPCI_CONFIG); switch (size) { From 2301a3e1a5664cf8380d2b8ef051005dc90bc881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 24 Sep 2022 11:24:04 +0200 Subject: [PATCH 266/401] PCI: mt7621: Use PCI_CONF1_EXT_ADDRESS() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify pcie-mt7621.c driver code and use new PCI_CONF1_EXT_ADDRESS() macro for accessing PCIe config space. Link: https://lore.kernel.org/r/20220924092404.31776-4-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Acked-by: Sergio Paracuellos --- drivers/pci/controller/pcie-mt7621.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/pci/controller/pcie-mt7621.c b/drivers/pci/controller/pcie-mt7621.c index 33eb37a2225c..4bd1abf26008 100644 --- a/drivers/pci/controller/pcie-mt7621.c +++ b/drivers/pci/controller/pcie-mt7621.c @@ -30,6 +30,8 @@ #include #include +#include "../pci.h" + /* MediaTek-specific configuration registers */ #define PCIE_FTS_NUM 0x70c #define PCIE_FTS_NUM_MASK GENMASK(15, 8) @@ -120,19 +122,12 @@ static inline void pcie_port_write(struct mt7621_pcie_port *port, writel_relaxed(val, port->base + reg); } -static inline u32 mt7621_pcie_get_cfgaddr(unsigned int bus, unsigned int slot, - unsigned int func, unsigned int where) -{ - return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) | - (func << 8) | (where & 0xfc) | 0x80000000; -} - static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, int where) { struct mt7621_pcie *pcie = bus->sysdata; - u32 address = mt7621_pcie_get_cfgaddr(bus->number, PCI_SLOT(devfn), - PCI_FUNC(devfn), where); + u32 address = PCI_CONF1_EXT_ADDRESS(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); @@ -147,7 +142,7 @@ static struct pci_ops mt7621_pcie_ops = { static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) { - u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); + u32 address = PCI_CONF1_EXT_ADDRESS(0, dev, 0, reg); pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); @@ -156,7 +151,7 @@ static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) static void write_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg, u32 val) { - u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); + u32 address = PCI_CONF1_EXT_ADDRESS(0, dev, 0, reg); pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); From 1abbe04a1b55200d0e3e93b2c15058c15126a225 Mon Sep 17 00:00:00 2001 From: Krishna chaitanya chundru Date: Thu, 8 Sep 2022 14:16:16 +0530 Subject: [PATCH 267/401] dt-bindings: pci: QCOM Add missing sc7280 aggre0, aggre1 clocks Add missing aggre0 and aggre1 clocks. Link: https://lore.kernel.org/r/1662626776-19636-3-git-send-email-quic_krichai@quicinc.com Signed-off-by: Krishna chaitanya chundru Signed-off-by: Lorenzo Pieralisi Reviewed-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/pci/qcom,pcie.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml index 7d29e2a45183..dd84f1487bed 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml @@ -54,11 +54,11 @@ properties: # Platform constraints are described later. clocks: minItems: 3 - maxItems: 12 + maxItems: 13 clock-names: minItems: 3 - maxItems: 12 + maxItems: 13 resets: minItems: 1 @@ -424,8 +424,8 @@ allOf: then: properties: clocks: - minItems: 11 - maxItems: 11 + minItems: 13 + maxItems: 13 clock-names: items: - const: pipe # PIPE clock @@ -439,6 +439,8 @@ allOf: - const: slave_q2a # Slave Q2A clock - const: tbu # PCIe TBU clock - const: ddrss_sf_tbu # PCIe SF TBU clock + - const: aggre0 # Aggre NoC PCIe CENTER SF AXI clock + - const: aggre1 # Aggre NoC PCIe1 AXI clock resets: maxItems: 1 reset-names: From 2b7672b0fa0b833312aef5a366a741921af3634f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 27 Sep 2022 08:42:36 -0700 Subject: [PATCH 268/401] Input: twl4030-pwrbutton - add missing of.h include The driver is using of_match_ptr() and therefore needs to include of.h header. Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220927052217.2784593-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl4030-pwrbutton.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index b307cca17022..e3ee0638ffba 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include From 9dedc915937c33302df7fcab01c45e7936d6195a Mon Sep 17 00:00:00 2001 From: zhang songyi Date: Tue, 27 Sep 2022 08:56:06 -0700 Subject: [PATCH 269/401] Input: synaptics-rmi4 - convert to use sysfs_emit() APIs Follow the advice of the Documentation/filesystems/sysfs.rst and show() should only use sysfs_emit() or sysfs_emit_at() when formatting the value to be returned to user space. Reported-by: Zeal Robot Signed-off-by: zhang songyi Link: https://lore.kernel.org/r/20220927070936.258300-1-zhang.songyi@zte.com.cn Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_f34.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c index 30169b584573..0d9a5756e3f5 100644 --- a/drivers/input/rmi4/rmi_f34.c +++ b/drivers/input/rmi4/rmi_f34.c @@ -321,13 +321,13 @@ static ssize_t rmi_driver_bootloader_id_show(struct device *dev, f34 = dev_get_drvdata(&fn->dev); if (f34->bl_version == 5) - return scnprintf(buf, PAGE_SIZE, "%c%c\n", - f34->bootloader_id[0], - f34->bootloader_id[1]); + return sysfs_emit(buf, "%c%c\n", + f34->bootloader_id[0], + f34->bootloader_id[1]); else - return scnprintf(buf, PAGE_SIZE, "V%d.%d\n", - f34->bootloader_id[1], - f34->bootloader_id[0]); + return sysfs_emit(buf, "V%d.%d\n", + f34->bootloader_id[1], + f34->bootloader_id[0]); } return 0; @@ -346,7 +346,7 @@ static ssize_t rmi_driver_configuration_id_show(struct device *dev, if (fn) { f34 = dev_get_drvdata(&fn->dev); - return scnprintf(buf, PAGE_SIZE, "%s\n", f34->configuration_id); + return sysfs_emit(buf, "%s\n", f34->configuration_id); } return 0; @@ -499,7 +499,7 @@ static ssize_t rmi_driver_update_fw_status_show(struct device *dev, if (data->f34_container) update_status = rmi_f34_status(data->f34_container); - return scnprintf(buf, PAGE_SIZE, "%d\n", update_status); + return sysfs_emit(buf, "%d\n", update_status); } static DEVICE_ATTR(update_fw_status, 0444, From 5459c0b7046752e519a646e1c2404852bb628459 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 16 Aug 2022 13:20:42 +0300 Subject: [PATCH 270/401] PCI/DPC: Quirk PIO log size for certain Intel Root Ports Some Root Ports on Intel Tiger Lake and Alder Lake systems support the RP Extensions for DPC and the RP PIO Log registers but incorrectly advertise an RP PIO Log Size of zero. This means the kernel complains that: DPC: RP PIO log size 0 is invalid and if DPC is triggered, the DPC driver will not dump the RP PIO Log registers when it should. This is caused by a BIOS bug and should be fixed the BIOS for future CPUs. Add a quirk to set the correct RP PIO Log size for the affected Root Ports. Link: https://bugzilla.kernel.org/show_bug.cgi?id=209943 Link: https://lore.kernel.org/r/20220816102042.69125-1-mika.westerberg@linux.intel.com Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Reviewed-by: Kuppuswamy Sathyanarayanan --- drivers/pci/pcie/dpc.c | 15 ++++++++++----- drivers/pci/quirks.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index 3e9afee02e8d..f5ffea17c7f8 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -335,11 +335,16 @@ void pci_dpc_init(struct pci_dev *pdev) return; pdev->dpc_rp_extensions = true; - pdev->dpc_rp_log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8; - if (pdev->dpc_rp_log_size < 4 || pdev->dpc_rp_log_size > 9) { - pci_err(pdev, "RP PIO log size %u is invalid\n", - pdev->dpc_rp_log_size); - pdev->dpc_rp_log_size = 0; + + /* Quirks may set dpc_rp_log_size if device or firmware is buggy */ + if (!pdev->dpc_rp_log_size) { + pdev->dpc_rp_log_size = + (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8; + if (pdev->dpc_rp_log_size < 4 || pdev->dpc_rp_log_size > 9) { + pci_err(pdev, "RP PIO log size %u is invalid\n", + pdev->dpc_rp_log_size); + pdev->dpc_rp_log_size = 0; + } } } diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 4944798e75b5..285acc4aaccc 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -5956,3 +5956,39 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56b1, aspm_l1_acceptable_latency DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56c0, aspm_l1_acceptable_latency); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56c1, aspm_l1_acceptable_latency); #endif + +#ifdef CONFIG_PCIE_DPC +/* + * Intel Tiger Lake and Alder Lake BIOS has a bug that clears the DPC + * RP PIO Log Size of the integrated Thunderbolt PCIe Root Ports. + */ +static void dpc_log_size(struct pci_dev *dev) +{ + u16 dpc, val; + + dpc = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC); + if (!dpc) + return; + + pci_read_config_word(dev, dpc + PCI_EXP_DPC_CAP, &val); + if (!(val & PCI_EXP_DPC_CAP_RP_EXT)) + return; + + if (!((val & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8)) { + pci_info(dev, "Overriding RP PIO Log Size to 4\n"); + dev->dpc_rp_log_size = 4; + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x461f, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x462f, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x463f, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x466e, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a23, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a25, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a27, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a29, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2b, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size); +#endif From 90c9978959dacdecfc30d2e6ad5cefc4823399b8 Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Tue, 27 Sep 2022 18:01:16 -0700 Subject: [PATCH 271/401] Input: xpad - refactor using BIT() macro reduces the amount of magic numbers and makes the code more readable Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20220913213133.584979-2-rojtberg@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 113 +++++++++++++++++----------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index fceb0d342945..2d9a92551499 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -61,6 +61,7 @@ * Later changes can be tracked in SCM. */ +#include #include #include #include @@ -709,10 +710,10 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d /* digital pad */ if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (left, right, up, down) */ - input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04); - input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08); - input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01); - input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02); + input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & BIT(2)); + input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & BIT(3)); + input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & BIT(0)); + input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & BIT(1)); } else { input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); @@ -721,10 +722,10 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d } /* start/back buttons and stick press left/right */ - input_report_key(dev, BTN_START, data[2] & 0x10); - input_report_key(dev, BTN_SELECT, data[2] & 0x20); - input_report_key(dev, BTN_THUMBL, data[2] & 0x40); - input_report_key(dev, BTN_THUMBR, data[2] & 0x80); + input_report_key(dev, BTN_START, data[2] & BIT(4)); + input_report_key(dev, BTN_SELECT, data[2] & BIT(5)); + input_report_key(dev, BTN_THUMBL, data[2] & BIT(6)); + input_report_key(dev, BTN_THUMBR, data[2] & BIT(7)); /* "analog" buttons A, B, X, Y */ input_report_key(dev, BTN_A, data[4]); @@ -759,10 +760,10 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, /* digital pad */ if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (left, right, up, down) */ - input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04); - input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08); - input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01); - input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02); + input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & BIT(2)); + input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & BIT(3)); + input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & BIT(0)); + input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & BIT(1)); } /* @@ -780,21 +781,21 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, } /* start/back buttons */ - input_report_key(dev, BTN_START, data[2] & 0x10); - input_report_key(dev, BTN_SELECT, data[2] & 0x20); + input_report_key(dev, BTN_START, data[2] & BIT(4)); + input_report_key(dev, BTN_SELECT, data[2] & BIT(5)); /* stick press left/right */ - input_report_key(dev, BTN_THUMBL, data[2] & 0x40); - input_report_key(dev, BTN_THUMBR, data[2] & 0x80); + input_report_key(dev, BTN_THUMBL, data[2] & BIT(6)); + input_report_key(dev, BTN_THUMBR, data[2] & BIT(7)); /* buttons A,B,X,Y,TL,TR and MODE */ - input_report_key(dev, BTN_A, data[3] & 0x10); - input_report_key(dev, BTN_B, data[3] & 0x20); - input_report_key(dev, BTN_X, data[3] & 0x40); - input_report_key(dev, BTN_Y, data[3] & 0x80); - input_report_key(dev, BTN_TL, data[3] & 0x01); - input_report_key(dev, BTN_TR, data[3] & 0x02); - input_report_key(dev, BTN_MODE, data[3] & 0x04); + input_report_key(dev, BTN_A, data[3] & BIT(4)); + input_report_key(dev, BTN_B, data[3] & BIT(5)); + input_report_key(dev, BTN_X, data[3] & BIT(6)); + input_report_key(dev, BTN_Y, data[3] & BIT(7)); + input_report_key(dev, BTN_TL, data[3] & BIT(0)); + input_report_key(dev, BTN_TR, data[3] & BIT(1)); + input_report_key(dev, BTN_MODE, data[3] & BIT(2)); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { /* left stick */ @@ -832,7 +833,7 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, } /* mode button down/up */ - if (data[3] & 0x04) + if (data[3] & BIT(2)) xpad->mode_btn_down_ts = ktime_get_seconds(); else xpad->mode_btn_down_ts = 0; @@ -928,7 +929,7 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char if (data[1] == 0x30) xpadone_ack_mode_report(xpad, data[2]); - input_report_key(dev, BTN_MODE, data[4] & 0x01); + input_report_key(dev, BTN_MODE, data[4] & BIT(0)); do_sync = true; } else if (data[0] == 0X0C) { @@ -942,33 +943,33 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char data[18] = 0; /* Elite Series 2 split packet paddle bits */ - input_report_key(dev, BTN_TRIGGER_HAPPY5, data[18] & 0x01); - input_report_key(dev, BTN_TRIGGER_HAPPY6, data[18] & 0x02); - input_report_key(dev, BTN_TRIGGER_HAPPY7, data[18] & 0x04); - input_report_key(dev, BTN_TRIGGER_HAPPY8, data[18] & 0x08); + input_report_key(dev, BTN_TRIGGER_HAPPY5, data[18] & BIT(0)); + input_report_key(dev, BTN_TRIGGER_HAPPY6, data[18] & BIT(1)); + input_report_key(dev, BTN_TRIGGER_HAPPY7, data[18] & BIT(2)); + input_report_key(dev, BTN_TRIGGER_HAPPY8, data[18] & BIT(3)); do_sync = true; } } else if (data[0] == 0X20) { /* The main valid packet type for inputs */ /* menu/view buttons */ - input_report_key(dev, BTN_START, data[4] & 0x04); - input_report_key(dev, BTN_SELECT, data[4] & 0x08); + input_report_key(dev, BTN_START, data[4] & BIT(2)); + input_report_key(dev, BTN_SELECT, data[4] & BIT(3)); if (xpad->mapping & MAP_SELECT_BUTTON) - input_report_key(dev, KEY_RECORD, data[22] & 0x01); + input_report_key(dev, KEY_RECORD, data[22] & BIT(0)); /* buttons A,B,X,Y */ - input_report_key(dev, BTN_A, data[4] & 0x10); - input_report_key(dev, BTN_B, data[4] & 0x20); - input_report_key(dev, BTN_X, data[4] & 0x40); - input_report_key(dev, BTN_Y, data[4] & 0x80); + input_report_key(dev, BTN_A, data[4] & BIT(4)); + input_report_key(dev, BTN_B, data[4] & BIT(5)); + input_report_key(dev, BTN_X, data[4] & BIT(6)); + input_report_key(dev, BTN_Y, data[4] & BIT(7)); /* digital pad */ if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (left, right, up, down) */ - input_report_key(dev, BTN_TRIGGER_HAPPY1, data[5] & 0x04); - input_report_key(dev, BTN_TRIGGER_HAPPY2, data[5] & 0x08); - input_report_key(dev, BTN_TRIGGER_HAPPY3, data[5] & 0x01); - input_report_key(dev, BTN_TRIGGER_HAPPY4, data[5] & 0x02); + input_report_key(dev, BTN_TRIGGER_HAPPY1, data[5] & BIT(2)); + input_report_key(dev, BTN_TRIGGER_HAPPY2, data[5] & BIT(3)); + input_report_key(dev, BTN_TRIGGER_HAPPY3, data[5] & BIT(0)); + input_report_key(dev, BTN_TRIGGER_HAPPY4, data[5] & BIT(1)); } else { input_report_abs(dev, ABS_HAT0X, !!(data[5] & 0x08) - !!(data[5] & 0x04)); @@ -977,12 +978,12 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char } /* TL/TR */ - input_report_key(dev, BTN_TL, data[5] & 0x10); - input_report_key(dev, BTN_TR, data[5] & 0x20); + input_report_key(dev, BTN_TL, data[5] & BIT(4)); + input_report_key(dev, BTN_TR, data[5] & BIT(5)); /* stick press left/right */ - input_report_key(dev, BTN_THUMBL, data[5] & 0x40); - input_report_key(dev, BTN_THUMBR, data[5] & 0x80); + input_report_key(dev, BTN_THUMBL, data[5] & BIT(6)); + input_report_key(dev, BTN_THUMBR, data[5] & BIT(7)); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { /* left stick */ @@ -1023,10 +1024,10 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char data[32] = 0; /* OG Elite Series Controller paddle bits */ - input_report_key(dev, BTN_TRIGGER_HAPPY5, data[32] & 0x02); - input_report_key(dev, BTN_TRIGGER_HAPPY6, data[32] & 0x08); - input_report_key(dev, BTN_TRIGGER_HAPPY7, data[32] & 0x01); - input_report_key(dev, BTN_TRIGGER_HAPPY8, data[32] & 0x04); + input_report_key(dev, BTN_TRIGGER_HAPPY5, data[32] & BIT(1)); + input_report_key(dev, BTN_TRIGGER_HAPPY6, data[32] & BIT(3)); + input_report_key(dev, BTN_TRIGGER_HAPPY7, data[32] & BIT(0)); + input_report_key(dev, BTN_TRIGGER_HAPPY8, data[32] & BIT(2)); } else if (xpad->packet_type == PKT_XBE2_FW_OLD) { /* Mute paddles if controller has a custom mapping applied. * Checked by comparing the current mapping @@ -1036,10 +1037,10 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char data[18] = 0; /* Elite Series 2 4.x firmware paddle bits */ - input_report_key(dev, BTN_TRIGGER_HAPPY5, data[18] & 0x01); - input_report_key(dev, BTN_TRIGGER_HAPPY6, data[18] & 0x02); - input_report_key(dev, BTN_TRIGGER_HAPPY7, data[18] & 0x04); - input_report_key(dev, BTN_TRIGGER_HAPPY8, data[18] & 0x08); + input_report_key(dev, BTN_TRIGGER_HAPPY5, data[18] & BIT(0)); + input_report_key(dev, BTN_TRIGGER_HAPPY6, data[18] & BIT(1)); + input_report_key(dev, BTN_TRIGGER_HAPPY7, data[18] & BIT(2)); + input_report_key(dev, BTN_TRIGGER_HAPPY8, data[18] & BIT(3)); } else if (xpad->packet_type == PKT_XBE2_FW_5_EARLY) { /* Mute paddles if controller has a custom mapping applied. * Checked by comparing the current mapping @@ -1051,10 +1052,10 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char /* Elite Series 2 5.x firmware paddle bits * (before the packet was split) */ - input_report_key(dev, BTN_TRIGGER_HAPPY5, data[22] & 0x01); - input_report_key(dev, BTN_TRIGGER_HAPPY6, data[22] & 0x02); - input_report_key(dev, BTN_TRIGGER_HAPPY7, data[22] & 0x04); - input_report_key(dev, BTN_TRIGGER_HAPPY8, data[22] & 0x08); + input_report_key(dev, BTN_TRIGGER_HAPPY5, data[22] & BIT(0)); + input_report_key(dev, BTN_TRIGGER_HAPPY6, data[22] & BIT(1)); + input_report_key(dev, BTN_TRIGGER_HAPPY7, data[22] & BIT(2)); + input_report_key(dev, BTN_TRIGGER_HAPPY8, data[22] & BIT(3)); } } From 677065244aa17265d7933782b1720cdf8727fcae Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Tue, 27 Sep 2022 18:02:05 -0700 Subject: [PATCH 272/401] Input: xpad - decipher xpadone packages with GIP defines only renames, no functional changes. Some of the packets we send seem superfluous now. Unfortunately I dont have the hardware to verify whether they are. Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20220913213133.584979-3-rojtberg@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 99 ++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 2d9a92551499..60859008372c 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -514,13 +514,52 @@ struct xboxone_init_packet { .len = ARRAY_SIZE(_data), \ } +/* + * starting with xbox one, the game input protocol is used + * magic numbers are taken from + * - https://github.com/xpadneo/gip-dissector/blob/main/src/gip-dissector.lua + * - https://github.com/medusalix/xone/blob/master/bus/protocol.c + */ +#define GIP_CMD_ACK 0x01 +#define GIP_CMD_IDENTIFY 0x04 +#define GIP_CMD_POWER 0x05 +#define GIP_CMD_AUTHENTICATE 0x06 +#define GIP_CMD_VIRTUAL_KEY 0x07 +#define GIP_CMD_RUMBLE 0x09 +#define GIP_CMD_LED 0x0a +#define GIP_CMD_FIRMWARE 0x0c +#define GIP_CMD_INPUT 0x20 + +#define GIP_SEQ0 0x00 + +#define GIP_OPT_ACK 0x10 +#define GIP_OPT_INTERNAL 0x20 + +/* + * length of the command payload encoded with + * https://en.wikipedia.org/wiki/LEB128 + * which is a no-op for N < 128 + */ +#define GIP_PL_LEN(N) (N) + +/* + * payload specific defines + */ +#define GIP_PWR_ON 0x00 +#define GIP_LED_ON 0x01 + +#define GIP_MOTOR_R BIT(0) +#define GIP_MOTOR_L BIT(1) +#define GIP_MOTOR_RT BIT(2) +#define GIP_MOTOR_LT BIT(3) +#define GIP_MOTOR_ALL (GIP_MOTOR_R | GIP_MOTOR_L | GIP_MOTOR_RT | GIP_MOTOR_LT) /* * This packet is required for all Xbox One pads with 2015 * or later firmware installed (or present from the factory). */ -static const u8 xboxone_fw2015_init[] = { - 0x05, 0x20, 0x00, 0x01, 0x00 +static const u8 xboxone_power_on[] = { + GIP_CMD_POWER, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(1), GIP_PWR_ON }; /* @@ -530,7 +569,7 @@ static const u8 xboxone_fw2015_init[] = { * Bluetooth mode. */ static const u8 xboxone_s_init[] = { - 0x05, 0x20, 0x00, 0x0f, 0x06 + GIP_CMD_POWER, GIP_OPT_INTERNAL, GIP_SEQ0, 0x0f, 0x06 }; /* @@ -547,9 +586,9 @@ static const u8 extra_input_packet_init[] = { * (0x0e6f:0x0165) to finish initialization and for Hori pads * (0x0f0d:0x0067) to make the analog sticks work. */ -static const u8 xboxone_hori_init[] = { - 0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a, - 0x00, 0x00, 0x00, 0x80, 0x00 +static const u8 xboxone_hori_ack_id[] = { + GIP_CMD_ACK, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(9), + 0x00, GIP_CMD_IDENTIFY, GIP_OPT_INTERNAL, 0x3a, 0x00, 0x00, 0x00, 0x80, 0x00 }; /* @@ -557,8 +596,8 @@ static const u8 xboxone_hori_init[] = { * sending input reports. These pads include: (0x0e6f:0x02ab), * (0x0e6f:0x02a4), (0x0e6f:0x02a6). */ -static const u8 xboxone_pdp_init1[] = { - 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14 +static const u8 xboxone_pdp_led_on[] = { + GIP_CMD_LED, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(3), 0x00, GIP_LED_ON, 0x14 }; /* @@ -566,8 +605,8 @@ static const u8 xboxone_pdp_init1[] = { * sending input reports. These pads include: (0x0e6f:0x02ab), * (0x0e6f:0x02a4), (0x0e6f:0x02a6). */ -static const u8 xboxone_pdp_init2[] = { - 0x06, 0x20, 0x00, 0x02, 0x01, 0x00 +static const u8 xboxone_pdp_auth[] = { + GIP_CMD_AUTHENTICATE, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(2), 0x01, 0x00 }; /* @@ -575,8 +614,8 @@ static const u8 xboxone_pdp_init2[] = { * sending input reports. One of those pads is (0x24c6:0x543a). */ static const u8 xboxone_rumblebegin_init[] = { - 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, - 0x1D, 0x1D, 0xFF, 0x00, 0x00 + GIP_CMD_RUMBLE, 0x00, GIP_SEQ0, GIP_PL_LEN(9), + 0x00, GIP_MOTOR_ALL, 0x00, 0x00, 0x1D, 0x1D, 0xFF, 0x00, 0x00 }; /* @@ -586,8 +625,8 @@ static const u8 xboxone_rumblebegin_init[] = { * spin up to enough speed to actually vibrate the gamepad. */ static const u8 xboxone_rumbleend_init[] = { - 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 + GIP_CMD_RUMBLE, 0x00, GIP_SEQ0, GIP_PL_LEN(9), + 0x00, GIP_MOTOR_ALL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* @@ -597,14 +636,14 @@ static const u8 xboxone_rumbleend_init[] = { * packet is going to be sent. */ static const struct xboxone_init_packet xboxone_init_packets[] = { - XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), - XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), - XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), + XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_ack_id), + XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_ack_id), + XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_power_on), XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init), XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init), XBOXONE_INIT_PKT(0x045e, 0x0b00, extra_input_packet_init), - XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1), - XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2), + XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_led_on), + XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_auth), XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init), XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init), @@ -920,19 +959,19 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char bool do_sync = false; /* the xbox button has its own special report */ - if (data[0] == 0X07) { + if (data[0] == GIP_CMD_VIRTUAL_KEY) { /* * The Xbox One S controller requires these reports to be * acked otherwise it continues sending them forever and * won't report further mode button events. */ - if (data[1] == 0x30) + if (data[1] == (GIP_OPT_ACK | GIP_OPT_INTERNAL)) xpadone_ack_mode_report(xpad, data[2]); input_report_key(dev, BTN_MODE, data[4] & BIT(0)); do_sync = true; - } else if (data[0] == 0X0C) { + } else if (data[0] == GIP_CMD_FIRMWARE) { /* Some packet formats force us to use this separate to poll paddle inputs */ if (xpad->packet_type == PKT_XBE2_FW_5_11) { /* Mute paddles if controller is in a custom profile slot @@ -950,7 +989,7 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char do_sync = true; } - } else if (data[0] == 0X20) { /* The main valid packet type for inputs */ + } else if (data[0] == GIP_CMD_INPUT) { /* The main valid packet type for inputs */ /* menu/view buttons */ input_report_key(dev, BTN_START, data[4] & BIT(2)); input_report_key(dev, BTN_SELECT, data[4] & BIT(3)); @@ -1363,8 +1402,8 @@ static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num) struct xpad_output_packet *packet = &xpad->out_packets[XPAD_OUT_CMD_IDX]; static const u8 mode_report_ack[] = { - 0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00 + GIP_CMD_ACK, GIP_OPT_INTERNAL, GIP_SEQ0, GIP_PL_LEN(9), + 0x00, GIP_CMD_VIRTUAL_KEY, GIP_OPT_INTERNAL, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 }; spin_lock_irqsave(&xpad->odata_lock, flags); @@ -1442,14 +1481,14 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect break; case XTYPE_XBOXONE: - packet->data[0] = 0x09; /* activate rumble */ + packet->data[0] = GIP_CMD_RUMBLE; /* activate rumble */ packet->data[1] = 0x00; packet->data[2] = xpad->odata_serial++; - packet->data[3] = 0x09; + packet->data[3] = GIP_PL_LEN(9); packet->data[4] = 0x00; - packet->data[5] = 0x0F; - packet->data[6] = 0x00; - packet->data[7] = 0x00; + packet->data[5] = GIP_MOTOR_ALL; + packet->data[6] = 0x00; /* left trigger */ + packet->data[7] = 0x00; /* right trigger */ packet->data[8] = strong / 512; /* left actuator */ packet->data[9] = weak / 512; /* right actuator */ packet->data[10] = 0xFF; /* on period */ From 05763c996f72ef934432639fe412f5193816fd9d Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Tue, 27 Sep 2022 13:38:14 +0000 Subject: [PATCH 273/401] ipmi: Remove unused struct watcher_entry After commit e86ee2d44b44("ipmi: Rework locking and shutdown for hot remove"), no one use struct watcher_entry, so remove it. Signed-off-by: Yuan Can Message-Id: <20220927133814.98929-1-yuancan@huawei.com> Signed-off-by: Corey Minyard --- drivers/char/ipmi/ipmi_msghandler.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index c8a3b208f923..49a1707693c9 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -736,12 +736,6 @@ static void intf_free(struct kref *ref) kfree(intf); } -struct watcher_entry { - int intf_num; - struct ipmi_smi *intf; - struct list_head link; -}; - int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) { struct ipmi_smi *intf; From 600655cdc076fb7688887b3819628c9d0878601c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 28 Sep 2022 14:05:48 +0300 Subject: [PATCH 274/401] Input: icn8505 - utilize acpi_get_subsystem_id() Replace open coded variant of recently introduced acpi_get_subsystem_id(). Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220928110548.43955-1-andriy.shevchenko@linux.intel.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/chipone_icn8505.c | 30 +++++++-------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/input/touchscreen/chipone_icn8505.c b/drivers/input/touchscreen/chipone_icn8505.c index f9ca5502ac8c..c421f4be2700 100644 --- a/drivers/input/touchscreen/chipone_icn8505.c +++ b/drivers/input/touchscreen/chipone_icn8505.c @@ -364,32 +364,20 @@ static irqreturn_t icn8505_irq(int irq, void *dev_id) static int icn8505_probe_acpi(struct icn8505_data *icn8505, struct device *dev) { - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - const char *subsys = "unknown"; - struct acpi_device *adev; - union acpi_object *obj; - acpi_status status; + const char *subsys; + int error; - adev = ACPI_COMPANION(dev); - if (!adev) - return -ENODEV; - - status = acpi_evaluate_object(adev->handle, "_SUB", NULL, &buffer); - if (ACPI_SUCCESS(status)) { - obj = buffer.pointer; - if (obj->type == ACPI_TYPE_STRING) - subsys = obj->string.pointer; - else - dev_warn(dev, "Warning ACPI _SUB did not return a string\n"); - } else { - dev_warn(dev, "Warning ACPI _SUB failed: %#x\n", status); - buffer.pointer = NULL; - } + subsys = acpi_get_subsystem_id(ACPI_HANDLE(dev)); + error = PTR_ERR_OR_ZERO(subsys); + if (error == -ENODATA) + subsys = "unknown"; + else if (error) + return error; snprintf(icn8505->firmware_name, sizeof(icn8505->firmware_name), "chipone/icn8505-%s.fw", subsys); - kfree(buffer.pointer); + kfree_const(subsys); return 0; } From 25d0bef5d1d0dc2f919baa033be157d5c313994c Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Wed, 28 Sep 2022 09:02:34 -0700 Subject: [PATCH 275/401] Input: ibm-panel - add missing MODULE_DEVICE_TABLE This patch adds missing MODULE_DEVICE_TABLE definition which generates correct modalias for automatic loading of this driver when it is built as an external module. Signed-off-by: Zeng Heng Link: https://lore.kernel.org/r/20220928143133.1809491-1-zengheng4@huawei.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ibm-panel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/misc/ibm-panel.c b/drivers/input/misc/ibm-panel.c index 094bcdb568f1..a8fba0054719 100644 --- a/drivers/input/misc/ibm-panel.c +++ b/drivers/input/misc/ibm-panel.c @@ -183,6 +183,7 @@ static const struct of_device_id ibm_panel_match[] = { { .compatible = "ibm,op-panel" }, { } }; +MODULE_DEVICE_TABLE(of, ibm_panel_match); static struct i2c_driver ibm_panel_driver = { .driver = { From c85c36798bc2ed12af04b6cc274aed5b02984647 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 28 Sep 2022 14:53:33 -0700 Subject: [PATCH 276/401] Input: ims-pcu - fix spelling mistake "BOOLTLOADER" -> "BOOTLOADER" There is a spelling mistake in a dev_err message. Fix it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20220928211003.61872-1-colin.i.king@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ims-pcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 6f38aa23a1ff..b2f1292e27ef 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -744,7 +744,7 @@ static int ims_pcu_switch_to_bootloader(struct ims_pcu *pcu) error = ims_pcu_execute_command(pcu, JUMP_TO_BTLDR, NULL, 0); if (error) { dev_err(pcu->dev, - "Failure when sending JUMP TO BOOLTLOADER command, error: %d\n", + "Failure when sending JUMP TO BOOTLOADER command, error: %d\n", error); return error; } From d218fe04335183518009f29f3270ec4dde1b66a2 Mon Sep 17 00:00:00 2001 From: Nate Yocom Date: Wed, 28 Sep 2022 18:10:35 -0700 Subject: [PATCH 277/401] Input: xpad - add X-Box Adaptive support Adds correct VID/PID for this XTYPE_XBOXONE compatible controller to xpad_device[] table. Signed-off-by: Nate Yocom Tested-by: Bastien Nocera Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20220908173930.28940-2-nate@yocom.org Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 60859008372c..1058ed28be49 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -148,6 +148,7 @@ static const struct xpad_device { { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE }, { 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE }, { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, + { 0x045e, 0x0b0a, "Microsoft X-Box Adaptive Controller", 0, XTYPE_XBOXONE }, { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE }, { 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, From f45aaae6204d1c7b0200ce043102ec84d805ac34 Mon Sep 17 00:00:00 2001 From: Nate Yocom Date: Wed, 28 Sep 2022 18:18:54 -0700 Subject: [PATCH 278/401] Input: xpad - add X-Box Adaptive XBox button Adaptive controller sets 0x02 bit for this button, all others set 0x01 so presence of either is used for BTN_MODE. Signed-off-by: Nate Yocom Tested-by: Bastien Nocera Reviewed-by: Mattijs Korpershoek --- drivers/input/joystick/xpad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 1058ed28be49..c66ae73523d2 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -969,7 +969,8 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char if (data[1] == (GIP_OPT_ACK | GIP_OPT_INTERNAL)) xpadone_ack_mode_report(xpad, data[2]); - input_report_key(dev, BTN_MODE, data[4] & BIT(0)); + input_report_key(dev, BTN_MODE, data[4] & GENMASK(1, 0)); + input_sync(dev); do_sync = true; } else if (data[0] == GIP_CMD_FIRMWARE) { From 1260cd04a601e0e02e09fa332111b8639611970d Mon Sep 17 00:00:00 2001 From: Nate Yocom Date: Wed, 28 Sep 2022 18:23:22 -0700 Subject: [PATCH 279/401] Input: add ABS_PROFILE to uapi and documentation Define new ABS_PROFILE axis for input devices which need it, e.g. X-Box Adaptive Controller and X-Box Elite 2. Signed-off-by: Nate Yocom Link: https://lore.kernel.org/r/20220908173930.28940-4-nate@yocom.org Signed-off-by: Dmitry Torokhov --- Documentation/input/event-codes.rst | 6 ++++++ Documentation/input/gamepad.rst | 6 ++++++ drivers/hid/hid-debug.c | 3 ++- include/uapi/linux/input-event-codes.h | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst index 8741d390b184..b4557462edd7 100644 --- a/Documentation/input/event-codes.rst +++ b/Documentation/input/event-codes.rst @@ -235,6 +235,12 @@ A few EV_ABS codes have special meanings: BTN_TOOL_ signals the type of tool that is currently detected by the hardware and is otherwise independent of ABS_DISTANCE and/or BTN_TOUCH. +* ABS_PROFILE: + + - Used to describe the state of a multi-value profile switch. An event is + emitted only when the selected profile changes, indicating the newly + selected profile value. + * ABS_MT_: - Used to describe multitouch input events. Please see diff --git a/Documentation/input/gamepad.rst b/Documentation/input/gamepad.rst index 4d5e7fb80a84..71019de46036 100644 --- a/Documentation/input/gamepad.rst +++ b/Documentation/input/gamepad.rst @@ -189,3 +189,9 @@ Gamepads report the following events: - Rumble: Rumble is advertised as FF_RUMBLE. + +- Profile: + + Some pads provide a multi-value profile selection switch. An example is the + XBox Adaptive and the XBox Elite 2 controllers. When the active profile is + switched, its newly selected value is emitted as an ABS_PROFILE event. diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 81e7e404a5fc..2ca6ab600bc9 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -1014,7 +1014,8 @@ static const char *absolutes[ABS_CNT] = { [ABS_HAT3Y] = "Hat 3Y", [ABS_PRESSURE] = "Pressure", [ABS_DISTANCE] = "Distance", [ABS_TILT_X] = "XTilt", [ABS_TILT_Y] = "YTilt", [ABS_TOOL_WIDTH] = "ToolWidth", - [ABS_VOLUME] = "Volume", [ABS_MISC] = "Misc", + [ABS_VOLUME] = "Volume", [ABS_PROFILE] = "Profile", + [ABS_MISC] = "Misc", [ABS_MT_TOUCH_MAJOR] = "MTMajor", [ABS_MT_TOUCH_MINOR] = "MTMinor", [ABS_MT_WIDTH_MAJOR] = "MTMajorW", diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index dff8e7f17074..7ad931a32970 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -862,6 +862,7 @@ #define ABS_TOOL_WIDTH 0x1c #define ABS_VOLUME 0x20 +#define ABS_PROFILE 0x21 #define ABS_MISC 0x28 From fff1011a26d6cbf26b18c8ee4c61d99943174f8c Mon Sep 17 00:00:00 2001 From: Nate Yocom Date: Wed, 28 Sep 2022 18:23:49 -0700 Subject: [PATCH 280/401] Input: xpad - add X-Box Adaptive Profile button Adds a new quirk for controllers that have a Profile button which has 4 states, reflected as an ABS_PROFILE axis with 4 values. Signed-off-by: Nate Yocom Tested-by: Bastien Nocera Link: https://lore.kernel.org/r/20220908173930.28940-6-nate@yocom.org Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index c66ae73523d2..2959d80f7fdb 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -81,7 +81,9 @@ #define MAP_TRIGGERS_TO_BUTTONS (1 << 1) #define MAP_STICKS_TO_NULL (1 << 2) #define MAP_SELECT_BUTTON (1 << 3) -#define MAP_PADDLES (1 << 4) +#define MAP_PADDLES (1 << 4) +#define MAP_PROFILE_BUTTON (1 << 5) + #define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) @@ -148,7 +150,7 @@ static const struct xpad_device { { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE }, { 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE }, { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, - { 0x045e, 0x0b0a, "Microsoft X-Box Adaptive Controller", 0, XTYPE_XBOXONE }, + { 0x045e, 0x0b0a, "Microsoft X-Box Adaptive Controller", MAP_PROFILE_BUTTON, XTYPE_XBOXONE }, { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE }, { 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, @@ -777,6 +779,10 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d input_report_key(dev, BTN_C, data[8]); input_report_key(dev, BTN_Z, data[9]); + /* Profile button has a value of 0-3, so it is reported as an axis */ + if (xpad->mapping & MAP_PROFILE_BUTTON) + input_report_abs(dev, ABS_PROFILE, data[34]); + input_sync(dev); } @@ -1800,6 +1806,9 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ input_set_abs_params(input_dev, abs, -1, 1, 0, 0); break; + case ABS_PROFILE: /* 4 value profile button (such as on XAC) */ + input_set_abs_params(input_dev, abs, 0, 4, 0, 0); + break; default: input_set_abs_params(input_dev, abs, 0, 0, 0, 0); break; @@ -1898,6 +1907,10 @@ static int xpad_init_input(struct usb_xpad *xpad) xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); } + /* setup profile button as an axis with 4 possible values */ + if (xpad->mapping & MAP_PROFILE_BUTTON) + xpad_set_up_abs(input_dev, ABS_PROFILE); + error = xpad_init_ff(xpad); if (error) goto err_free_input; From b623023225abed7a7d76cf1cc9f7187c1a3e7cff Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 28 Sep 2022 17:54:20 +0200 Subject: [PATCH 281/401] PCI: qcom: Drop unused post_deinit callback Drop the unused and confusingly named post_deinit callback that was added for the now removed pipe clock handling. If ever needed we can add back a callback named pre_deinit (or perhaps rather pre_phy_power_off) instead. Link: https://lore.kernel.org/r/20220928155421.21660-2-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 39ca06ffe614..8d6df0db4ebb 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -208,7 +208,6 @@ struct qcom_pcie_ops { int (*init)(struct qcom_pcie *pcie); int (*post_init)(struct qcom_pcie *pcie); void (*deinit)(struct qcom_pcie *pcie); - void (*post_deinit)(struct qcom_pcie *pcie); void (*ltssm_enable)(struct qcom_pcie *pcie); int (*config_sid)(struct qcom_pcie *pcie); }; @@ -1520,8 +1519,6 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp) err: qcom_ep_reset_assert(pcie); - if (pcie->cfg->ops->post_deinit) - pcie->cfg->ops->post_deinit(pcie); err_disable_phy: phy_power_off(pcie->phy); err_deinit: From 0e4d9a5cc7670d59e73cc372263a7417330aa56f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 28 Sep 2022 17:54:21 +0200 Subject: [PATCH 282/401] PCI: qcom: Rename host-init error label Use a more descriptive name for the reset host-init error label for consistency. Link: https://lore.kernel.org/r/20220928155421.21660-3-johan+linaro@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 8d6df0db4ebb..f711acacaeaf 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1512,12 +1512,12 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp) if (pcie->cfg->ops->config_sid) { ret = pcie->cfg->ops->config_sid(pcie); if (ret) - goto err; + goto err_assert_reset; } return 0; -err: +err_assert_reset: qcom_ep_reset_assert(pcie); err_disable_phy: phy_power_off(pcie->phy); From 8bb7ff12a91429eb76e093b517ae810b146448fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 28 Sep 2022 14:19:11 +0200 Subject: [PATCH 283/401] PCI: tegra: Use PCI_CONF1_EXT_ADDRESS() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify pci-tegra.c driver code and use new PCI_CONF1_EXT_ADDRESS() macro for accessing PCI config space. Link: https://lore.kernel.org/r/20220928121911.14994-1-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Acked-by: Thierry Reding --- drivers/pci/controller/pci-tegra.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 8e323e93be91..24478ae5a345 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -415,13 +415,6 @@ static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset) * address (access to which generates correct config transaction) falls in * this 4 KiB region. */ -static unsigned int tegra_pcie_conf_offset(u8 bus, unsigned int devfn, - unsigned int where) -{ - return ((where & 0xf00) << 16) | (bus << 16) | (PCI_SLOT(devfn) << 11) | - (PCI_FUNC(devfn) << 8) | (where & 0xff); -} - static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, int where) @@ -443,7 +436,9 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus, unsigned int offset; u32 base; - offset = tegra_pcie_conf_offset(bus->number, devfn, where); + offset = PCI_CONF1_EXT_ADDRESS(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where) & + ~PCI_CONF1_ENABLE; /* move 4 KiB window to offset within the FPCI region */ base = 0xfe100000 + ((offset & ~(SZ_4K - 1)) >> 8); From 3e347969a5776947a115649dae740a9ed47473f5 Mon Sep 17 00:00:00 2001 From: Sajid Dalvi Date: Wed, 21 Sep 2022 21:27:35 +0000 Subject: [PATCH 284/401] PCI/PM: Reduce D3hot delay with usleep_range() PCIe r6.0, sec 5.9, requires a 10ms delay between programming a device to change to or from D3hot and the time the device is next accessed (unless Readiness Notifications are used). The 10ms value (PCI_PM_D3HOT_WAIT) doesn't appear directly here because some chipsets require 120ms for devices *below* them (pci_pm_d3hot_delay) and some devices require more or less than 10ms (dev->d3hot_delay). But msleep(10) typically waits about *20*ms, which is more than we need. Switch to usleep_range() to improve the delay accuracy. Based on a commit from Sajid in the Pixel 6 kernel tree [1]. On a Pixel 6, the 10ms delay for the Exynos PCIe device delayed for an average of 19ms. Switching to usleep_range() decreased the resume time by about 9ms. [1] https://android.googlesource.com/kernel/gs/+/18a8cad68d8e6d50f339a716a18295e6d987cee3 [bhelgaas commit log, add timers-howto.rst link] Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/timers/timers-howto.rst?id=v5.19#n73 Link: https://lore.kernel.org/r/20220921212735.2131588-1-willmcvicker@google.com Signed-off-by: Sajid Dalvi Signed-off-by: Will McVicker Signed-off-by: Bjorn Helgaas Reviewed-by: Matthias Kaehlcke --- drivers/pci/pci.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 107afa0a5b03..92c6f7e5ca2e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -66,13 +66,15 @@ struct pci_pme_device { static void pci_dev_d3_sleep(struct pci_dev *dev) { - unsigned int delay = dev->d3hot_delay; + unsigned int delay_ms = max(dev->d3hot_delay, pci_pm_d3hot_delay); + unsigned int upper; - if (delay < pci_pm_d3hot_delay) - delay = pci_pm_d3hot_delay; - - if (delay) - msleep(delay); + if (delay_ms) { + /* Use a 20% upper bound, 1ms minimum */ + upper = max(DIV_ROUND_CLOSEST(delay_ms, 5), 1U); + usleep_range(delay_ms * USEC_PER_MSEC, + (delay_ms + upper) * USEC_PER_MSEC); + } } bool pci_reset_supported(struct pci_dev *dev) From 2d09ac951b7750780ecb3de3ccb642dffd7ef62b Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 29 Sep 2022 21:11:36 +0200 Subject: [PATCH 285/401] input: drop empty comment blocks Commit 1a59d1b8e05e ("treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156") has left some empty comment blocks. Remove them to save a few lines of code. Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/26a2b905b259bfffaf2de5b26f2007b8606970ed.1664478665.git.christophe.jaillet@wanadoo.fr Signed-off-by: Dmitry Torokhov --- drivers/input/ff-core.c | 3 --- drivers/input/ff-memless.c | 3 --- drivers/input/gameport/emu10k1-gp.c | 3 --- drivers/input/gameport/lightning.c | 3 --- drivers/input/gameport/ns558.c | 3 --- drivers/input/joystick/a3d.c | 3 --- drivers/input/joystick/adi.c | 3 --- drivers/input/joystick/amijoy.c | 3 --- drivers/input/joystick/analog.c | 3 --- drivers/input/joystick/cobra.c | 3 --- drivers/input/joystick/db9.c | 3 --- drivers/input/joystick/gamecon.c | 3 --- drivers/input/joystick/gf2k.c | 3 --- drivers/input/joystick/grip.c | 3 --- drivers/input/joystick/guillemot.c | 3 --- drivers/input/joystick/interact.c | 3 --- drivers/input/joystick/joydump.c | 3 --- drivers/input/joystick/magellan.c | 3 --- drivers/input/joystick/sidewinder.c | 3 --- drivers/input/joystick/spaceball.c | 3 --- drivers/input/joystick/spaceorb.c | 3 --- drivers/input/joystick/stinger.c | 3 --- drivers/input/joystick/tmdc.c | 3 --- drivers/input/joystick/turbografx.c | 3 --- drivers/input/joystick/twidjoy.c | 3 --- drivers/input/joystick/warrior.c | 3 --- drivers/input/joystick/zhenhua.c | 3 --- drivers/input/keyboard/amikbd.c | 3 --- drivers/input/keyboard/atakbd.c | 3 --- drivers/input/keyboard/lkkbd.c | 3 --- drivers/input/keyboard/newtonkbd.c | 3 --- drivers/input/keyboard/stowaway.c | 3 --- drivers/input/keyboard/sunkbd.c | 3 --- drivers/input/keyboard/xtkbd.c | 3 --- drivers/input/mouse/inport.c | 3 --- drivers/input/mouse/logibm.c | 3 --- drivers/input/mouse/pc110pad.c | 3 --- drivers/input/mouse/sermouse.c | 3 --- drivers/input/mouse/vsxxxaa.c | 3 --- drivers/input/serio/ct82c710.c | 3 --- drivers/input/serio/q40kbd.c | 3 --- drivers/input/serio/rpckbd.c | 3 --- drivers/input/serio/serio.c | 3 --- drivers/input/tablet/acecad.c | 3 --- drivers/input/tablet/hanwang.c | 3 --- drivers/input/touchscreen/gunze.c | 3 --- 46 files changed, 138 deletions(-) diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index fa8d1a466014..16231fe080b0 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -6,9 +6,6 @@ * Copyright (c) 2006 Dmitry Torokhov */ -/* - */ - /* #define DEBUG */ #include diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index 8229a9006917..c321cdabd214 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -6,9 +6,6 @@ * Copyright (c) 2006 Dmitry Torokhov */ -/* - */ - /* #define DEBUG */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index 11bbd1edfdb4..76ce41e58df0 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c @@ -7,9 +7,6 @@ * EMU10k1 - SB Live / Audigy - gameport driver for Linux */ -/* - */ - #include #include diff --git a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c index 87eeb4b5b5b5..2ce717b25a84 100644 --- a/drivers/input/gameport/lightning.c +++ b/drivers/input/gameport/lightning.c @@ -7,9 +7,6 @@ * PDPI Lightning 4 gamecard driver for Linux. */ -/* - */ - #include #include #include diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c index 2f80b7f1b736..91a8cd346e9b 100644 --- a/drivers/input/gameport/ns558.c +++ b/drivers/input/gameport/ns558.c @@ -8,9 +8,6 @@ * NS558 based standard IBM game port driver for Linux */ -/* - */ - #include #include diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 68475fad177c..fd1827baf27c 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -7,9 +7,6 @@ * FP-Gaming Assassin 3D joystick driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index e10d57bf1180..f1a720be458b 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -7,9 +7,6 @@ * Logitech ADI joystick family driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index 12456a196dc7..3752dc2a2086 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c @@ -7,9 +7,6 @@ * Driver for Amiga joysticks for Linux/m68k */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 3088c5b829f0..0c9e172a9818 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -7,9 +7,6 @@ * Analog joystick and gamepad driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 41e1936a847b..7ff78c9388bd 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -7,9 +7,6 @@ * Creative Labs Blaster GamePad Cobra driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 434d265fa2e8..4fba28b1a1e7 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -10,9 +10,6 @@ * Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index d37645e496ff..41d5dac05448 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -11,9 +11,6 @@ * Raphael Assenat */ -/* - */ - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 920feba967f6..abefbd1484df 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -7,9 +7,6 @@ * Genius Flight 2000 joystick driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index fe798bc87950..0e86b269a90e 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -7,9 +7,6 @@ * Gravis/Kensington GrIP protocol joystick and gamepad driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 8eeacdb007c1..205eb6f8b84d 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -7,9 +7,6 @@ * Guillemot Digital Interface Protocol driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index ca22d84e5c84..03a9f0829f7e 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -10,9 +10,6 @@ * InterAct digital gamepad/joystick driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c index 70f63f9550e7..865652a7821d 100644 --- a/drivers/input/joystick/joydump.c +++ b/drivers/input/joystick/joydump.c @@ -8,9 +8,6 @@ * out of the joystick port into the syslog ... */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index edb8e1982e26..017ef8c6170b 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -7,9 +7,6 @@ * Magellan and Space Mouse 6dof controller driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 8e9672deb1eb..7282301c3ae7 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -7,9 +7,6 @@ * Microsoft SideWinder joystick family driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index a85a4f33aea8..fa8ec533cd69 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -11,9 +11,6 @@ * SpaceTec SpaceBall 2003/3003/4000 FLX driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index 557171483256..dbbc69f17c89 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -10,9 +10,6 @@ * SpaceTec SpaceOrb 360 and Avenger 6dof controller driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index c20425f52bd8..530de468cb61 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -8,9 +8,6 @@ * Gravis Stinger gamepad driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index 7416de84b955..93562ecc0ca1 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -10,9 +10,6 @@ * ThrustMaster DirectConnect (BSP) joystick family driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index dfe7a2cacce2..dfb9c684651f 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -10,9 +10,6 @@ * TurboGraFX parallel port interface driver for Linux. */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 174c69a188fb..9b6792ac27f1 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -32,9 +32,6 @@ * Arndt Schoenewald */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 42bdbc28d95d..f66bddf145c2 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -7,9 +7,6 @@ * Logitech WingMan Warrior joystick driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/joystick/zhenhua.c b/drivers/input/joystick/zhenhua.c index d5531179b01f..3f2460e2b095 100644 --- a/drivers/input/joystick/zhenhua.c +++ b/drivers/input/joystick/zhenhua.c @@ -28,9 +28,6 @@ * coder :-( */ -/* - */ - #include #include #include diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 09551f64d53f..a20a4e186639 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -10,9 +10,6 @@ * Amiga keyboard driver for Linux/m68k */ -/* - */ - #include #include #include diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c index 77ed54630601..07e17e563f9b 100644 --- a/drivers/input/keyboard/atakbd.c +++ b/drivers/input/keyboard/atakbd.c @@ -21,9 +21,6 @@ * This driver only deals with handing key events off to the input layer. */ -/* - */ - #include #include #include diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index ea9a1d8834c1..047b654b3752 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -46,9 +46,6 @@ * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1 */ -/* - */ - #include #include #include diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index 9742261b2d1a..df00a119aa9a 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c @@ -7,9 +7,6 @@ * Newton keyboard driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index a4977193dd4a..56e784936059 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c @@ -10,9 +10,6 @@ * by Justin Cormack */ -/* - */ - #include #include #include diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index d450f11b98a7..b123a208ef36 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -7,9 +7,6 @@ * Sun keyboard driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index 280796df679a..c9d7c2481726 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c @@ -7,9 +7,6 @@ * XT keyboard driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index df5d1160478c..401d8bff8e84 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c @@ -13,9 +13,6 @@ * Inport (ATI XL and Microsoft) busmouse driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c index bd647f9f505a..0aab63dbc30a 100644 --- a/drivers/input/mouse/logibm.c +++ b/drivers/input/mouse/logibm.c @@ -14,9 +14,6 @@ * Logitech Bus Mouse Driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index f75574766b85..efa58049f746 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c @@ -10,9 +10,6 @@ * IBM PC110 touchpad driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index caa79c177c55..993f90333380 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -7,9 +7,6 @@ * Serial mouse driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 3bd6e723a422..8af8e4a15f95 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -12,9 +12,6 @@ * Later on, I had access to the device's documentation (referenced below). */ -/* - */ - /* * Building an adaptor to DE9 / DB25 RS232 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 752ce60e2211..3da751f4a6bf 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -7,9 +7,6 @@ * 82C710 C&T mouse port chip driver for Linux */ -/* - */ - #include #include #include diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index a1c61f5de047..ba04058fc3cb 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -10,9 +10,6 @@ * Q40 PS/2 keyboard controller driver for Linux/m68k */ -/* - */ - #include #include #include diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 7008bc101415..ce420eb1f51b 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -8,9 +8,6 @@ * Acorn RiscPC PS/2 keyboard controller driver for Linux/ARM */ -/* - */ - #include #include #include diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index ec117be3d8d8..15ce3202322f 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -7,9 +7,6 @@ * Copyright (c) 2003 Daniele Bellucci */ -/* - */ - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index 80e06727464d..b20e5a1afbcc 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c @@ -9,9 +9,6 @@ * v3.2 - Added sysfs support */ -/* - */ - #include #include #include diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c index e492a0331b24..9bc631518b92 100644 --- a/drivers/input/tablet/hanwang.c +++ b/drivers/input/tablet/hanwang.c @@ -5,9 +5,6 @@ * Copyright (c) 2010 Xing Wei */ -/* - */ - #include #include #include diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index e07e8e0fe8ea..5a5f9da73fa1 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -7,9 +7,6 @@ * Gunze AHL-51S touchscreen driver for Linux */ -/* - */ - #include #include #include From 1d666ab2dad5b311cd7d742607afcc59a2558925 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 30 Sep 2022 20:50:18 -0700 Subject: [PATCH 286/401] dt-bindings: input: Convert hid-over-i2c to DT schema Convert the hid-over-i2c binding to DT schema format. The supplies should probably be specific to a specific device, but it seems they are already in use otherwise. 'wakeup-source' is added as it was not explicitly documented. There's a few warnings for undocumented properties 'vcc-supply' and 'reset-gpios'. Those remain as they probably should have a specific compatible as well. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220927150916.1091217-1-robh@kernel.org Signed-off-by: Dmitry Torokhov --- .../bindings/input/hid-over-i2c.txt | 46 ---------- .../bindings/input/hid-over-i2c.yaml | 83 +++++++++++++++++++ 2 files changed, 83 insertions(+), 46 deletions(-) delete mode 100644 Documentation/devicetree/bindings/input/hid-over-i2c.txt create mode 100644 Documentation/devicetree/bindings/input/hid-over-i2c.yaml diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.txt b/Documentation/devicetree/bindings/input/hid-over-i2c.txt deleted file mode 100644 index 34c43d3bddfd..000000000000 --- a/Documentation/devicetree/bindings/input/hid-over-i2c.txt +++ /dev/null @@ -1,46 +0,0 @@ -* HID over I2C Device-Tree bindings - -HID over I2C provides support for various Human Interface Devices over the -I2C bus. These devices can be for example touchpads, keyboards, touch screens -or sensors. - -The specification has been written by Microsoft and is currently available here: -http://msdn.microsoft.com/en-us/library/windows/hardware/hh852380.aspx - -If this binding is used, the kernel module i2c-hid will handle the communication -with the device and the generic hid core layer will handle the protocol. - -Required properties: -- compatible: must be "hid-over-i2c" -- reg: i2c slave address -- hid-descr-addr: HID descriptor address -- interrupts: interrupt line - -Additional optional properties: - -Some devices may support additional optional properties to help with, e.g., -power sequencing. The following properties can be supported by one or more -device-specific compatible properties, which should be used in addition to the -"hid-over-i2c" string. - -- compatible: - * "wacom,w9013" (Wacom W9013 digitizer). Supports: - - vdd-supply (3.3V) - - vddl-supply (1.8V) - - post-power-on-delay-ms - -- vdd-supply: phandle of the regulator that provides the supply voltage. -- post-power-on-delay-ms: time required by the device after enabling its regulators - or powering it on, before it is ready for communication. -- touchscreen-inverted-x: See touchscreen.txt -- touchscreen-inverted-y: See touchscreen.txt - -Example: - - i2c-hid-dev@2c { - compatible = "hid-over-i2c"; - reg = <0x2c>; - hid-descr-addr = <0x0020>; - interrupt-parent = <&gpx3>; - interrupts = <3 2>; - }; diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.yaml b/Documentation/devicetree/bindings/input/hid-over-i2c.yaml new file mode 100644 index 000000000000..7156b08f7645 --- /dev/null +++ b/Documentation/devicetree/bindings/input/hid-over-i2c.yaml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/hid-over-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HID over I2C Devices + +maintainers: + - Benjamin Tissoires + - Jiri Kosina + +description: |+ + HID over I2C provides support for various Human Interface Devices over the + I2C bus. These devices can be for example touchpads, keyboards, touch screens + or sensors. + + The specification has been written by Microsoft and is currently available here: + https://msdn.microsoft.com/en-us/library/windows/hardware/hh852380.aspx + + If this binding is used, the kernel module i2c-hid will handle the communication + with the device and the generic hid core layer will handle the protocol. + +allOf: + - $ref: /schemas/input/touchscreen/touchscreen.yaml# + +properties: + compatible: + oneOf: + - items: + - enum: + - wacom,w9013 + - const: hid-over-i2c + - description: Just "hid-over-i2c" alone is allowed, but not recommended. + const: hid-over-i2c + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + hid-descr-addr: + description: HID descriptor address + $ref: /schemas/types.yaml#/definitions/uint32 + + post-power-on-delay-ms: + description: Time required by the device after enabling its regulators + or powering it on, before it is ready for communication. + + touchscreen-inverted-x: true + + touchscreen-inverted-y: true + + vdd-supply: + description: 3.3V supply + + vddl-supply: + description: 1.8V supply + + wakeup-source: true + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + hid@2c { + compatible = "hid-over-i2c"; + reg = <0x2c>; + hid-descr-addr = <0x0020>; + interrupts = <3 2>; + }; + }; +... From 75024261403af74051e6aeb1b0a2dc2bca2458dc Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 30 Sep 2022 22:52:34 -0700 Subject: [PATCH 287/401] dt-bindings: input: Add the PinePhone keyboard binding Add devicetree support for the PinePhone keyboard case, which provides a matrix keyboard interface and a proxied I2C bus. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20220618165747.55709-2-samuel@sholland.org Signed-off-by: Dmitry Torokhov --- .../input/pine64,pinephone-keyboard.yaml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/pine64,pinephone-keyboard.yaml diff --git a/Documentation/devicetree/bindings/input/pine64,pinephone-keyboard.yaml b/Documentation/devicetree/bindings/input/pine64,pinephone-keyboard.yaml new file mode 100644 index 000000000000..e4a0ac0fff9a --- /dev/null +++ b/Documentation/devicetree/bindings/input/pine64,pinephone-keyboard.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/pine64,pinephone-keyboard.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Pine64 PinePhone keyboard device tree bindings + +maintainers: + - Samuel Holland + +description: + A keyboard accessory is available for the Pine64 PinePhone and PinePhone Pro. + It connects via I2C, providing a raw scan matrix, a flashing interface, and a + subordinate I2C bus for communication with a battery charger IC. + +properties: + compatible: + const: pine64,pinephone-keyboard + + reg: + const: 0x15 + + interrupts: + maxItems: 1 + + vbat-supply: + description: Supply for the keyboard MCU + + wakeup-source: true + + i2c: + $ref: /schemas/i2c/i2c-controller.yaml# + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + keyboard@15 { + compatible = "pine64,pinephone-keyboard"; + reg = <0x15>; + interrupt-parent = <&r_pio>; + interrupts = <0 12 IRQ_TYPE_EDGE_FALLING>; /* PL12 */ + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + charger@75 { + reg = <0x75>; + }; + }; + }; + }; From 0dbc45241dc3f8d51957d4c770c16e49387cd6c2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 30 Aug 2022 21:33:10 +0300 Subject: [PATCH 288/401] PCI: dwc: Replace of_gpio_named_count() by gpiod_count() As a preparation to unexport of_gpio_named_count(), convert the driver to use gpiod_count() instead. Link: https://lore.kernel.org/r/20220830183310.48541-1-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Signed-off-by: Lorenzo Pieralisi Acked-by: Rob Herring --- drivers/pci/controller/dwc/pcie-kirin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c index 7f67aad71df4..d09507f822a7 100644 --- a/drivers/pci/controller/dwc/pcie-kirin.c +++ b/drivers/pci/controller/dwc/pcie-kirin.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -366,12 +367,11 @@ static int kirin_pcie_get_gpio_enable(struct kirin_pcie *pcie, struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; char name[32]; int ret, i; /* This is an optional property */ - ret = of_gpio_named_count(np, "hisilicon,clken-gpios"); + ret = gpiod_count(dev, "hisilicon,clken"); if (ret < 0) return 0; From 3db1e531e444290f0f54dd794b5cc22cf189930a Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Fri, 2 Sep 2022 16:58:06 +0800 Subject: [PATCH 289/401] PCI: imx6: Add i.MX8MP PCIe support Add i.MX8MP PCIe support. To avoid codes duplication when find the syscon regmap, add the iomux gpr syscon compatible into drvdata. Link: https://lore.kernel.org/r/1662109086-15881-8-git-send-email-hongxing.zhu@nxp.com Tested-by: Marek Vasut Tested-by: Richard Leitner Tested-by: Alexander Stein Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi Reviewed-by: Lucas Stach --- drivers/pci/controller/dwc/pci-imx6.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 6e5debdbc55b..facc8e7b01c2 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -51,6 +51,7 @@ enum imx6_pcie_variants { IMX7D, IMX8MQ, IMX8MM, + IMX8MP, }; #define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) @@ -61,6 +62,7 @@ struct imx6_pcie_drvdata { enum imx6_pcie_variants variant; u32 flags; int dbi_length; + const char *gpr; }; struct imx6_pcie { @@ -150,7 +152,8 @@ struct imx6_pcie { static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) { WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ && - imx6_pcie->drvdata->variant != IMX8MM); + imx6_pcie->drvdata->variant != IMX8MM && + imx6_pcie->drvdata->variant != IMX8MP); return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14; } @@ -301,6 +304,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) { switch (imx6_pcie->drvdata->variant) { case IMX8MM: + case IMX8MP: /* * The PHY initialization had been done in the PHY * driver, break here directly. @@ -558,6 +562,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) break; case IMX8MM: case IMX8MQ: + case IMX8MP: ret = clk_prepare_enable(imx6_pcie->pcie_aux); if (ret) { dev_err(dev, "unable to enable pcie_aux clock\n"); @@ -602,6 +607,7 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie) break; case IMX8MM: case IMX8MQ: + case IMX8MP: clk_disable_unprepare(imx6_pcie->pcie_aux); break; default: @@ -669,6 +675,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) reset_control_assert(imx6_pcie->pciephy_reset); fallthrough; case IMX8MM: + case IMX8MP: reset_control_assert(imx6_pcie->apps_reset); break; case IMX6SX: @@ -744,6 +751,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) break; case IMX6Q: /* Nothing to do */ case IMX8MM: + case IMX8MP: break; } @@ -793,6 +801,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev) case IMX7D: case IMX8MQ: case IMX8MM: + case IMX8MP: reset_control_deassert(imx6_pcie->apps_reset); break; } @@ -812,6 +821,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev) case IMX7D: case IMX8MQ: case IMX8MM: + case IMX8MP: reset_control_assert(imx6_pcie->apps_reset); break; } @@ -1179,6 +1189,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) } break; case IMX8MM: + case IMX8MP: imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); if (IS_ERR(imx6_pcie->pcie_aux)) return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux), @@ -1216,7 +1227,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) /* Grab GPR config register range */ imx6_pcie->iomuxc_gpr = - syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); + syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr); if (IS_ERR(imx6_pcie->iomuxc_gpr)) { dev_err(dev, "unable to find iomuxc registers\n"); return PTR_ERR(imx6_pcie->iomuxc_gpr); @@ -1295,12 +1306,14 @@ static const struct imx6_pcie_drvdata drvdata[] = { .flags = IMX6_PCIE_FLAG_IMX6_PHY | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, .dbi_length = 0x200, + .gpr = "fsl,imx6q-iomuxc-gpr", }, [IMX6SX] = { .variant = IMX6SX, .flags = IMX6_PCIE_FLAG_IMX6_PHY | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE | IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .gpr = "fsl,imx6q-iomuxc-gpr", }, [IMX6QP] = { .variant = IMX6QP, @@ -1308,17 +1321,26 @@ static const struct imx6_pcie_drvdata drvdata[] = { IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE | IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, .dbi_length = 0x200, + .gpr = "fsl,imx6q-iomuxc-gpr", }, [IMX7D] = { .variant = IMX7D, .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .gpr = "fsl,imx7d-iomuxc-gpr", }, [IMX8MQ] = { .variant = IMX8MQ, + .gpr = "fsl,imx8mq-iomuxc-gpr", }, [IMX8MM] = { .variant = IMX8MM, .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .gpr = "fsl,imx8mm-iomuxc-gpr", + }, + [IMX8MP] = { + .variant = IMX8MP, + .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, + .gpr = "fsl,imx8mp-iomuxc-gpr", }, }; @@ -1329,6 +1351,7 @@ static const struct of_device_id imx6_pcie_of_match[] = { { .compatible = "fsl,imx7d-pcie", .data = &drvdata[IMX7D], }, { .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], }, { .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], }, + { .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], }, {}, }; From cbcf8722b523dcf0970ab67dc3d5ced1ea7b334e Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 5 Sep 2022 10:23:03 +0800 Subject: [PATCH 290/401] phy: freescale: imx8m-pcie: Fix the wrong order of phy_init() and phy_power_on() Refer to phy_core driver, phy_init() must be called before phy_power_on(). Fix the wrong order of phy_init() and phy_power_on() here. Link: https://lore.kernel.org/r/1662344583-18874-1-git-send-email-hongxing.zhu@nxp.com Fixes: 1aa97b002258 ("phy: freescale: pcie: Initialize the imx8 pcie standalone phy driver") Tested-by: Alexander Stein Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi Acked-by: Vinod Koul Acked-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pci-imx6.c | 6 +++--- drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index facc8e7b01c2..2616585ca5f8 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -945,7 +945,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp) } if (imx6_pcie->phy) { - ret = phy_power_on(imx6_pcie->phy); + ret = phy_init(imx6_pcie->phy); if (ret) { dev_err(dev, "pcie PHY power up failed\n"); goto err_clk_disable; @@ -959,7 +959,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp) } if (imx6_pcie->phy) { - ret = phy_init(imx6_pcie->phy); + ret = phy_power_on(imx6_pcie->phy); if (ret) { dev_err(dev, "waiting for PHY ready timeout!\n"); goto err_phy_off; @@ -971,7 +971,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp) err_phy_off: if (imx6_pcie->phy) - phy_power_off(imx6_pcie->phy); + phy_exit(imx6_pcie->phy); err_clk_disable: imx6_pcie_clk_disable(imx6_pcie); err_reg_disable: diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c index ad7d2edfc414..c93286483b42 100644 --- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c +++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c @@ -59,7 +59,7 @@ struct imx8_pcie_phy { bool clkreq_unused; }; -static int imx8_pcie_phy_init(struct phy *phy) +static int imx8_pcie_phy_power_on(struct phy *phy) { int ret; u32 val, pad_mode; @@ -137,14 +137,14 @@ static int imx8_pcie_phy_init(struct phy *phy) return ret; } -static int imx8_pcie_phy_power_on(struct phy *phy) +static int imx8_pcie_phy_init(struct phy *phy) { struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy); return clk_prepare_enable(imx8_phy->clk); } -static int imx8_pcie_phy_power_off(struct phy *phy) +static int imx8_pcie_phy_exit(struct phy *phy) { struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy); @@ -155,8 +155,8 @@ static int imx8_pcie_phy_power_off(struct phy *phy) static const struct phy_ops imx8_pcie_phy_ops = { .init = imx8_pcie_phy_init, + .exit = imx8_pcie_phy_exit, .power_on = imx8_pcie_phy_power_on, - .power_off = imx8_pcie_phy_power_off, .owner = THIS_MODULE, }; From f1bfbd000f3bc42a34aec9208c6aaa9076682601 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:39 +0530 Subject: [PATCH 291/401] PCI: qcom-ep: Add kernel-doc for qcom_pcie_ep structure Add kernel-doc for qcom_pcie_ep structure. Link: https://lore.kernel.org/r/20220914075350.7992-2-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 4c87167861fd..98c64a85d01f 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -140,6 +140,23 @@ static struct clk_bulk_data qcom_pcie_ep_clks[] = { { .id = "slave_q2a" }, }; +/** + * struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller + * @pci: Designware PCIe controller struct + * @parf: Qualcomm PCIe specific PARF register base + * @elbi: Designware PCIe specific ELBI register base + * @perst_map: PERST regmap + * @mmio_res: MMIO region resource + * @core_reset: PCIe Endpoint core reset + * @reset: PERST# GPIO + * @wake: WAKE# GPIO + * @phy: PHY controller block + * @perst_en: Flag for PERST enable + * @perst_sep_en: Flag for PERST separation enable + * @link_status: PCIe Link status + * @global_irq: Qualcomm PCIe specific Global IRQ + * @perst_irq: PERST# IRQ + */ struct qcom_pcie_ep { struct dw_pcie pci; From e2efd31465b1d97a0bca6f93cb75ccdc8001c8d3 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:40 +0530 Subject: [PATCH 292/401] PCI: qcom-ep: Rely on the clocks supplied by devicetree Generally, device drivers should just rely on the platform data like devicetree to supply the clocks required for the functioning of the peripheral. There is no need to hardcode the clk info in the driver. So get rid of the static clk info and obtain the platform supplied clks. The total number of clocks supplied is obtained using the devm_clk_bulk_get_all() API and used for the rest of the clk_bulk_ APIs. Link: https://lore.kernel.org/r/20220914075350.7992-3-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 33 +++++++++-------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 98c64a85d01f..e6ba781594a6 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -130,16 +130,6 @@ enum qcom_pcie_ep_link_status { QCOM_PCIE_EP_LINK_DOWN, }; -static struct clk_bulk_data qcom_pcie_ep_clks[] = { - { .id = "cfg" }, - { .id = "aux" }, - { .id = "bus_master" }, - { .id = "bus_slave" }, - { .id = "ref" }, - { .id = "sleep" }, - { .id = "slave_q2a" }, -}; - /** * struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller * @pci: Designware PCIe controller struct @@ -151,6 +141,8 @@ static struct clk_bulk_data qcom_pcie_ep_clks[] = { * @reset: PERST# GPIO * @wake: WAKE# GPIO * @phy: PHY controller block + * @clks: PCIe clocks + * @num_clks: PCIe clocks count * @perst_en: Flag for PERST enable * @perst_sep_en: Flag for PERST separation enable * @link_status: PCIe Link status @@ -170,6 +162,9 @@ struct qcom_pcie_ep { struct gpio_desc *wake; struct phy *phy; + struct clk_bulk_data *clks; + int num_clks; + u32 perst_en; u32 perst_sep_en; @@ -244,8 +239,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep) { int ret; - ret = clk_bulk_prepare_enable(ARRAY_SIZE(qcom_pcie_ep_clks), - qcom_pcie_ep_clks); + ret = clk_bulk_prepare_enable(pcie_ep->num_clks, pcie_ep->clks); if (ret) return ret; @@ -266,8 +260,7 @@ static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep) err_phy_exit: phy_exit(pcie_ep->phy); err_disable_clk: - clk_bulk_disable_unprepare(ARRAY_SIZE(qcom_pcie_ep_clks), - qcom_pcie_ep_clks); + clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks); return ret; } @@ -276,8 +269,7 @@ static void qcom_pcie_disable_resources(struct qcom_pcie_ep *pcie_ep) { phy_power_off(pcie_ep->phy); phy_exit(pcie_ep->phy); - clk_bulk_disable_unprepare(ARRAY_SIZE(qcom_pcie_ep_clks), - qcom_pcie_ep_clks); + clk_bulk_disable_unprepare(pcie_ep->num_clks, pcie_ep->clks); } static int qcom_pcie_perst_deassert(struct dw_pcie *pci) @@ -495,10 +487,11 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev, return ret; } - ret = devm_clk_bulk_get(dev, ARRAY_SIZE(qcom_pcie_ep_clks), - qcom_pcie_ep_clks); - if (ret) - return ret; + pcie_ep->num_clks = devm_clk_bulk_get_all(dev, &pcie_ep->clks); + if (pcie_ep->num_clks < 0) { + dev_err(dev, "Failed to get clocks\n"); + return pcie_ep->num_clks; + } pcie_ep->core_reset = devm_reset_control_get_exclusive(dev, "core"); if (IS_ERR(pcie_ep->core_reset)) From 9cf4843e1acf08ab5c523bc4fa8f7b24de2bea3a Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:41 +0530 Subject: [PATCH 293/401] PCI: qcom-ep: Make use of the cached dev pointer In the qcom_pcie_ep_get_resources() function, dev pointer is already cached in a local variable. So let's make use of it instead of getting the dev pointer again from pdev struct. Link: https://lore.kernel.org/r/20220914075350.7992-4-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index e6ba781594a6..51afd9c547f5 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -483,7 +483,7 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev, ret = qcom_pcie_ep_get_io_resources(pdev, pcie_ep); if (ret) { - dev_err(&pdev->dev, "Failed to get io resources %d\n", ret); + dev_err(dev, "Failed to get io resources %d\n", ret); return ret; } @@ -505,7 +505,7 @@ static int qcom_pcie_ep_get_resources(struct platform_device *pdev, if (IS_ERR(pcie_ep->wake)) return PTR_ERR(pcie_ep->wake); - pcie_ep->phy = devm_phy_optional_get(&pdev->dev, "pciephy"); + pcie_ep->phy = devm_phy_optional_get(dev, "pciephy"); if (IS_ERR(pcie_ep->phy)) ret = PTR_ERR(pcie_ep->phy); From 44159659df8ca381b84261e11058b2176fa03ba0 Mon Sep 17 00:00:00 2001 From: Shida Zhang Date: Tue, 4 Oct 2022 16:39:42 +1100 Subject: [PATCH 294/401] xfs: trim the mapp array accordingly in xfs_da_grow_inode_int Take a look at the for-loop in xfs_da_grow_inode_int: ====== for(){ nmap = min(XFS_BMAP_MAX_NMAP, count); ... error = xfs_bmapi_write(...,&mapp[mapi], &nmap);//(..., $1, $2) ... mapi += nmap; } ===== where $1 stands for the start address of the array, while $2 is used to indicate the size of the array. The array $1 will advance by $nmap in each iteration after the allocation of extents. But the size $2 still remains unchanged, which is determined by min(XFS_BMAP_MAX_NMAP, count). It seems that it has forgotten to trim the mapp array after each iteration, so change it. Signed-off-by: Shida Zhang Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_da_btree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index e7201dc68f43..e576560b46e9 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2192,8 +2192,8 @@ xfs_da_grow_inode_int( */ mapp = kmem_alloc(sizeof(*mapp) * count, 0); for (b = *bno, mapi = 0; b < *bno + count; ) { - nmap = min(XFS_BMAP_MAX_NMAP, count); c = (int)(*bno + count - b); + nmap = min(XFS_BMAP_MAX_NMAP, c); error = xfs_bmapi_write(tp, dp, b, c, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, args->total, &mapp[mapi], &nmap); From c098576f5f63bc0ee2424bba50892514a71d54e8 Mon Sep 17 00:00:00 2001 From: Shida Zhang Date: Tue, 4 Oct 2022 16:39:58 +1100 Subject: [PATCH 295/401] xfs: rearrange the logic and remove the broken comment for xfs_dir2_isxx xfs_dir2_isleaf is used to see if the directory is a single-leaf form directory instead, as commented right above the function. Besides getting rid of the broken comment, we rearrange the logic by converting everything over to standard formatting and conventions, at the same time, to make it easier to understand and self documenting. Signed-off-by: Shida Zhang Reviewed-by: Darrick J. Wong Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_dir2.c | 50 +++++++++++++++++++++++---------------- fs/xfs/libxfs/xfs_dir2.h | 4 ++-- fs/xfs/scrub/dir.c | 2 +- fs/xfs/xfs_dir2_readdir.c | 2 +- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 76eedc2756b3..92bac3373f1f 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -261,7 +261,7 @@ xfs_dir_createname( { struct xfs_da_args *args; int rval; - int v; /* type-checking value */ + bool v; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -357,7 +357,7 @@ xfs_dir_lookup( { struct xfs_da_args *args; int rval; - int v; /* type-checking value */ + bool v; int lock_mode; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -435,7 +435,7 @@ xfs_dir_removename( { struct xfs_da_args *args; int rval; - int v; /* type-checking value */ + bool v; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); XFS_STATS_INC(dp->i_mount, xs_dir_remove); @@ -493,7 +493,7 @@ xfs_dir_replace( { struct xfs_da_args *args; int rval; - int v; /* type-checking value */ + bool v; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -610,19 +610,23 @@ xfs_dir2_grow_inode( int xfs_dir2_isblock( struct xfs_da_args *args, - int *vp) /* out: 1 is block, 0 is not block */ + bool *isblock) { - xfs_fileoff_t last; /* last file offset */ - int rval; + struct xfs_mount *mp = args->dp->i_mount; + xfs_fileoff_t eof; + int error; - if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK))) - return rval; - rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize; - if (XFS_IS_CORRUPT(args->dp->i_mount, - rval != 0 && - args->dp->i_disk_size != args->geo->blksize)) + error = xfs_bmap_last_offset(args->dp, &eof, XFS_DATA_FORK); + if (error) + return error; + + *isblock = false; + if (XFS_FSB_TO_B(mp, eof) != args->geo->blksize) + return 0; + + *isblock = true; + if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize)) return -EFSCORRUPTED; - *vp = rval; return 0; } @@ -632,14 +636,20 @@ xfs_dir2_isblock( int xfs_dir2_isleaf( struct xfs_da_args *args, - int *vp) /* out: 1 is block, 0 is not block */ + bool *isleaf) { - xfs_fileoff_t last; /* last file offset */ - int rval; + xfs_fileoff_t eof; + int error; - if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK))) - return rval; - *vp = last == args->geo->leafblk + args->geo->fsbcount; + error = xfs_bmap_last_offset(args->dp, &eof, XFS_DATA_FORK); + if (error) + return error; + + *isleaf = false; + if (eof != args->geo->leafblk + args->geo->fsbcount) + return 0; + + *isleaf = true; return 0; } diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index b6df3c34b26a..dd39f17dd9a9 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -61,8 +61,8 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args); /* * Interface routines used by userspace utilities */ -extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r); -extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r); +extern int xfs_dir2_isblock(struct xfs_da_args *args, bool *isblock); +extern int xfs_dir2_isleaf(struct xfs_da_args *args, bool *isleaf); extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, struct xfs_buf *bp); diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 5abb5fdb71d9..b9c5764e7437 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -676,7 +676,7 @@ xchk_directory_blocks( xfs_dablk_t dabno; xfs_dir2_db_t last_data_db = 0; bool found; - int is_block = 0; + bool is_block = false; int error; /* Ignore local format directories. */ diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index e295fc8062d8..9f3ceb461515 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -512,7 +512,7 @@ xfs_readdir( { struct xfs_da_args args = { NULL }; unsigned int lock_mode; - int isblock; + bool isblock; int error; trace_xfs_readdir(dp); From e033f40be262c4d227f8fbde52856e1d8646872b Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 4 Oct 2022 16:40:01 +1100 Subject: [PATCH 296/401] xfs: on memory failure, only shut down fs after scanning all mappings xfs_dax_failure_fn is used to scan the filesystem during a memory failure event to look for memory mappings to revoke. Unfortunately, if it encounters an rmap record for filesystem metadata, it will shut down the filesystem and the scan immediately. This means that we don't complete the mapping revocation scan and instead leave live mappings to failed memory. Fix the function to defer the shutdown until after we've finished culling mappings. While we're at it, add the usual "xfs_" prefix to struct failure_info, and actually initialize mf_flags. Fixes: 6f643c57d57c ("xfs: implement ->notify_failure() for XFS") Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_notify_failure.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_notify_failure.c b/fs/xfs/xfs_notify_failure.c index 69d9c83ea4b2..65d5eb20878e 100644 --- a/fs/xfs/xfs_notify_failure.c +++ b/fs/xfs/xfs_notify_failure.c @@ -23,17 +23,18 @@ #include #include -struct failure_info { +struct xfs_failure_info { xfs_agblock_t startblock; xfs_extlen_t blockcount; int mf_flags; + bool want_shutdown; }; static pgoff_t xfs_failure_pgoff( struct xfs_mount *mp, const struct xfs_rmap_irec *rec, - const struct failure_info *notify) + const struct xfs_failure_info *notify) { loff_t pos = XFS_FSB_TO_B(mp, rec->rm_offset); @@ -47,7 +48,7 @@ static unsigned long xfs_failure_pgcnt( struct xfs_mount *mp, const struct xfs_rmap_irec *rec, - const struct failure_info *notify) + const struct xfs_failure_info *notify) { xfs_agblock_t end_rec; xfs_agblock_t end_notify; @@ -71,13 +72,13 @@ xfs_dax_failure_fn( { struct xfs_mount *mp = cur->bc_mp; struct xfs_inode *ip; - struct failure_info *notify = data; + struct xfs_failure_info *notify = data; int error = 0; if (XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) || (rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))) { - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_ONDISK); - return -EFSCORRUPTED; + notify->want_shutdown = true; + return 0; } /* Get files that incore, filter out others that are not in use. */ @@ -86,8 +87,10 @@ xfs_dax_failure_fn( /* Continue the rmap query if the inode isn't incore */ if (error == -ENODATA) return 0; - if (error) - return error; + if (error) { + notify->want_shutdown = true; + return 0; + } error = mf_dax_kill_procs(VFS_I(ip)->i_mapping, xfs_failure_pgoff(mp, rec, notify), @@ -104,6 +107,7 @@ xfs_dax_notify_ddev_failure( xfs_daddr_t bblen, int mf_flags) { + struct xfs_failure_info notify = { .mf_flags = mf_flags }; struct xfs_trans *tp = NULL; struct xfs_btree_cur *cur = NULL; struct xfs_buf *agf_bp = NULL; @@ -120,7 +124,6 @@ xfs_dax_notify_ddev_failure( for (; agno <= end_agno; agno++) { struct xfs_rmap_irec ri_low = { }; struct xfs_rmap_irec ri_high; - struct failure_info notify; struct xfs_agf *agf; xfs_agblock_t agend; struct xfs_perag *pag; @@ -161,6 +164,11 @@ xfs_dax_notify_ddev_failure( } xfs_trans_cancel(tp); + if (error || notify.want_shutdown) { + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_ONDISK); + if (!error) + error = -EFSCORRUPTED; + } return error; } From 4635c0e2a7f7f3568cbfccae70121f9835efa62c Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Fri, 30 Sep 2022 15:20:32 +0200 Subject: [PATCH 297/401] pinctrl: rockchip: add pinmux_ops.gpio_set_direction callback Before the split of gpio and pinctrl sections in their own driver, rockchip_set_mux was called in pinmux_ops.gpio_set_direction for configuring a pin in its GPIO function. This is essential for cases where pinctrl is "bypassed" by gpio consumers otherwise the GPIO function is not configured for the pin and it does not work. Such was the case for the sysfs/libgpiod userspace GPIO handling. Let's re-implement the pinmux_ops.gpio_set_direction callback so that the gpio subsystem can request from the pinctrl driver to put the pin in its GPIO function. Fixes: 9ce9a02039de ("pinctrl/rockchip: drop the gpio related codes") Cc: stable@vger.kernel.org Reviewed-by: Heiko Stuebner Signed-off-by: Quentin Schulz Link: https://lore.kernel.org/r/20220930132033.4003377-2-foss+kernel@0leil.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index a91061f9c2ac..53bdfc40f055 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -2665,11 +2665,24 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, return 0; } +static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset, + bool input) +{ + struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + struct rockchip_pin_bank *bank; + + bank = pin_to_bank(info, offset); + return rockchip_set_mux(bank, offset - bank->pin_base, RK_FUNC_GPIO); +} + static const struct pinmux_ops rockchip_pmx_ops = { .get_functions_count = rockchip_pmx_get_funcs_count, .get_function_name = rockchip_pmx_get_func_name, .get_function_groups = rockchip_pmx_get_groups, .set_mux = rockchip_pmx_set, + .gpio_set_direction = rockchip_pmx_gpio_set_direction, }; /* From 8ea8af6c8469156ac2042d83d73f6b74eb4b4b45 Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Fri, 30 Sep 2022 15:20:33 +0200 Subject: [PATCH 298/401] gpio: rockchip: request GPIO mux to pinctrl when setting direction Before the split of gpio and pinctrl sections in their own driver, rockchip_set_mux was called in pinmux_ops.gpio_set_direction for configuring a pin in its GPIO function. This is essential for cases where pinctrl is "bypassed" by gpio consumers otherwise the GPIO function is not configured for the pin and it does not work. Such was the case for the sysfs/libgpiod userspace GPIO handling. Let's call pinctrl_gpio_direction_input/output when setting the direction of a GPIO so that the pinctrl core requests from the rockchip pinctrl driver to put the pin in its GPIO function. Fixes: 9ce9a02039de ("pinctrl/rockchip: drop the gpio related codes") Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio") Cc: stable@vger.kernel.org Reviewed-by: Heiko Stuebner Signed-off-by: Quentin Schulz Link: https://lore.kernel.org/r/20220930132033.4003377-3-foss+kernel@0leil.net Signed-off-by: Linus Walleij --- drivers/gpio/gpio-rockchip.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index f91e876fd969..2bde8365b125 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -156,6 +157,12 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip, unsigned long flags; u32 data = input ? 0 : 1; + + if (input) + pinctrl_gpio_direction_input(bank->pin_base + offset); + else + pinctrl_gpio_direction_output(bank->pin_base + offset); + raw_spin_lock_irqsave(&bank->slock, flags); rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr); raw_spin_unlock_irqrestore(&bank->slock, flags); From 19fdcb1d98a6adcab27db4cc0d111fcba0f7bd8f Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Fri, 23 Sep 2022 18:10:38 +0800 Subject: [PATCH 299/401] pinctrl: bcm: ns: Remove redundant dev_err call devm_ioremap_resource() prints error message in itself. Remove the dev_err call to avoid redundant error message. Signed-off-by: Shang XiaoJing Acked-by: Florian Fainelli Acked-by: Ray Jui Link: https://lore.kernel.org/r/20220923101038.18036-1-shangxiaojing@huawei.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-ns.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-ns.c b/drivers/pinctrl/bcm/pinctrl-ns.c index 65a86543c58c..465cc96814a1 100644 --- a/drivers/pinctrl/bcm/pinctrl-ns.c +++ b/drivers/pinctrl/bcm/pinctrl-ns.c @@ -233,10 +233,8 @@ static int ns_pinctrl_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cru_gpio_control"); ns_pinctrl->base = devm_ioremap_resource(dev, res); - if (IS_ERR(ns_pinctrl->base)) { - dev_err(dev, "Failed to map pinctrl regs\n"); + if (IS_ERR(ns_pinctrl->base)) return PTR_ERR(ns_pinctrl->base); - } memcpy(pctldesc, &ns_pinctrl_desc, sizeof(*pctldesc)); From 203672e1208c2f36ff31a305f6a70d73d9dbce63 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 25 Sep 2022 13:21:03 +0200 Subject: [PATCH 300/401] pinctrl: qcom: restrict drivers per ARM/ARM64 There is no point to allow selecting pin-controller drivers for Qualcomm ARMv7 SoCs when building ARM64 kernel, and vice versa. This makes kernel configuration more difficult as many do not remember the Qualcomm SoCs. There won't be a single image for ARMv7 and ARMv8/9 SoCs, so no features/options are lost. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220925112103.148836-1-krzysztof.kozlowski@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Kconfig | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 2961b5eb8e10..9dc2d803a586 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -15,6 +15,7 @@ config PINCTRL_MSM config PINCTRL_APQ8064 tristate "Qualcomm APQ8064 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -23,6 +24,7 @@ config PINCTRL_APQ8064 config PINCTRL_APQ8084 tristate "Qualcomm APQ8084 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -31,6 +33,7 @@ config PINCTRL_APQ8084 config PINCTRL_IPQ4019 tristate "Qualcomm IPQ4019 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -39,6 +42,7 @@ config PINCTRL_IPQ4019 config PINCTRL_IPQ8064 tristate "Qualcomm IPQ8064 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -47,6 +51,7 @@ config PINCTRL_IPQ8064 config PINCTRL_IPQ8074 tristate "Qualcomm Technologies, Inc. IPQ8074 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for @@ -57,6 +62,7 @@ config PINCTRL_IPQ8074 config PINCTRL_IPQ6018 tristate "Qualcomm Technologies, Inc. IPQ6018 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for @@ -67,6 +73,7 @@ config PINCTRL_IPQ6018 config PINCTRL_MSM8226 tristate "Qualcomm 8226 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -76,6 +83,7 @@ config PINCTRL_MSM8226 config PINCTRL_MSM8660 tristate "Qualcomm 8660 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -84,6 +92,7 @@ config PINCTRL_MSM8660 config PINCTRL_MSM8960 tristate "Qualcomm 8960 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -100,6 +109,7 @@ config PINCTRL_MDM9607 config PINCTRL_MDM9615 tristate "Qualcomm 9615 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -108,6 +118,7 @@ config PINCTRL_MDM9615 config PINCTRL_MSM8X74 tristate "Qualcomm 8x74 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -116,6 +127,7 @@ config PINCTRL_MSM8X74 config PINCTRL_MSM8909 tristate "Qualcomm 8909 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -132,6 +144,7 @@ config PINCTRL_MSM8916 config PINCTRL_MSM8953 tristate "Qualcomm 8953 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -142,6 +155,7 @@ config PINCTRL_MSM8953 config PINCTRL_MSM8976 tristate "Qualcomm 8976 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -152,6 +166,7 @@ config PINCTRL_MSM8976 config PINCTRL_MSM8994 tristate "Qualcomm 8994 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -161,6 +176,7 @@ config PINCTRL_MSM8994 config PINCTRL_MSM8996 tristate "Qualcomm MSM8996 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -169,6 +185,7 @@ config PINCTRL_MSM8996 config PINCTRL_MSM8998 tristate "Qualcomm MSM8998 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -177,6 +194,7 @@ config PINCTRL_MSM8998 config PINCTRL_QCM2290 tristate "Qualcomm QCM2290 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -185,6 +203,7 @@ config PINCTRL_QCM2290 config PINCTRL_QCS404 tristate "Qualcomm QCS404 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -232,6 +251,7 @@ config PINCTRL_QCOM_SSBI_PMIC config PINCTRL_SC7180 tristate "Qualcomm Technologies Inc SC7180 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -241,6 +261,7 @@ config PINCTRL_SC7180 config PINCTRL_SC7280 tristate "Qualcomm Technologies Inc SC7280 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -250,6 +271,7 @@ config PINCTRL_SC7280 config PINCTRL_SC7280_LPASS_LPI tristate "Qualcomm Technologies Inc SC7280 LPASS LPI pin controller driver" depends on GPIOLIB + depends on ARM64 || COMPILE_TEST depends on PINCTRL_LPASS_LPI help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -259,6 +281,7 @@ config PINCTRL_SC7280_LPASS_LPI config PINCTRL_SC8180X tristate "Qualcomm Technologies Inc SC8180x pin controller driver" depends on (OF || ACPI) + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -268,6 +291,7 @@ config PINCTRL_SC8180X config PINCTRL_SC8280XP tristate "Qualcomm Technologies Inc SC8280xp pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -277,6 +301,7 @@ config PINCTRL_SC8280XP config PINCTRL_SDM660 tristate "Qualcomm Technologies Inc SDM660 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -286,6 +311,7 @@ config PINCTRL_SDM660 config PINCTRL_SDM845 tristate "Qualcomm Technologies Inc SDM845 pin controller driver" depends on (OF || ACPI) + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -295,6 +321,7 @@ config PINCTRL_SDM845 config PINCTRL_SDX55 tristate "Qualcomm Technologies Inc SDX55 pin controller driver" depends on OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -304,6 +331,7 @@ config PINCTRL_SDX55 config PINCTRL_SM6115 tristate "Qualcomm Technologies Inc SM6115,SM4250 pin controller driver" depends on GPIOLIB && OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -313,6 +341,7 @@ config PINCTRL_SM6115 config PINCTRL_SM6125 tristate "Qualcomm Technologies Inc SM6125 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -322,6 +351,7 @@ config PINCTRL_SM6125 config PINCTRL_SM6350 tristate "Qualcomm Technologies Inc SM6350 pin controller driver" depends on GPIOLIB && OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -331,6 +361,7 @@ config PINCTRL_SM6350 config PINCTRL_SM6375 tristate "Qualcomm Technologies Inc SM6375 pin controller driver" depends on GPIOLIB && OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -340,6 +371,7 @@ config PINCTRL_SM6375 config PINCTRL_SDX65 tristate "Qualcomm Technologies Inc SDX65 pin controller driver" depends on GPIOLIB && OF + depends on ARM || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -349,6 +381,7 @@ config PINCTRL_SDX65 config PINCTRL_SM8150 tristate "Qualcomm Technologies Inc SM8150 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -358,6 +391,7 @@ config PINCTRL_SM8150 config PINCTRL_SM8250 tristate "Qualcomm Technologies Inc SM8250 pin controller driver" depends on OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -367,6 +401,7 @@ config PINCTRL_SM8250 config PINCTRL_SM8250_LPASS_LPI tristate "Qualcomm Technologies Inc SM8250 LPASS LPI pin controller driver" depends on GPIOLIB + depends on ARM64 || COMPILE_TEST depends on PINCTRL_LPASS_LPI help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -375,6 +410,7 @@ config PINCTRL_SM8250_LPASS_LPI config PINCTRL_SM8350 tristate "Qualcomm Technologies Inc SM8350 pin controller driver" + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -384,6 +420,7 @@ config PINCTRL_SM8350 config PINCTRL_SM8450 tristate "Qualcomm Technologies Inc SM8450 pin controller driver" depends on GPIOLIB && OF + depends on ARM64 || COMPILE_TEST depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -393,6 +430,7 @@ config PINCTRL_SM8450 config PINCTRL_SM8450_LPASS_LPI tristate "Qualcomm Technologies Inc SM8450 LPASS LPI pin controller driver" depends on GPIOLIB + depends on ARM64 || COMPILE_TEST depends on PINCTRL_LPASS_LPI help This is the pinctrl, pinmux, pinconf and gpiolib driver for the @@ -402,6 +440,7 @@ config PINCTRL_SM8450_LPASS_LPI config PINCTRL_SC8280XP_LPASS_LPI tristate "Qualcomm Technologies Inc SC8280XP LPASS LPI pin controller driver" depends on GPIOLIB + depends on ARM64 || COMPILE_TEST depends on PINCTRL_LPASS_LPI help This is the pinctrl, pinmux, pinconf and gpiolib driver for the From 66db794ad54ce49d4fd564a16f682f257f608655 Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Tue, 27 Sep 2022 13:39:26 +0000 Subject: [PATCH 301/401] pinctrl: bcm: Remove unused struct bcm6328_pingroup After commit 0e3db16300fb("pinctrl: bcm: Convert drivers to use struct pingroup and PINCTRL_PINGROUP()"), no one use struct bcm6328_pingroup, so remove it. Signed-off-by: Yuan Can Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220927133926.103943-1-yuancan@huawei.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm6328.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm6328.c b/drivers/pinctrl/bcm/pinctrl-bcm6328.c index 1eef5ab9a5e5..1e8cc2c80c81 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm6328.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm6328.c @@ -26,12 +26,6 @@ #define BCM6328_MUX_OTHER_REG 0x24 #define BCM6328_MUX_MASK GENMASK(1, 0) -struct bcm6328_pingroup { - const char *name; - const unsigned * const pins; - const unsigned num_pins; -}; - struct bcm6328_function { const char *name; const char * const *groups; From f4a31facfa80df2f440a2fdc2b7f58d6c23925b0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 27 Sep 2022 20:55:09 +0300 Subject: [PATCH 302/401] pinctrl: wpcm450: Correct the fwnode_irq_get() return value check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fwnode_irq_get() can return zero to indicate IRQ mapping errors. Handle this case by skipping the interrupt resource. Fixes: a1d1e0e3d80a ("pinctrl: nuvoton: Add driver for WPCM450") Signed-off-by: Andy Shevchenko Reviewed-by: Jonathan Neuschäfer Link: https://lore.kernel.org/r/20220927175509.15695-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/nuvoton/pinctrl-wpcm450.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c b/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c index 0dbeb91f0bf2..8193b92da403 100644 --- a/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c +++ b/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c @@ -1081,10 +1081,13 @@ static int wpcm450_gpio_register(struct platform_device *pdev, girq->num_parents = 0; for (i = 0; i < WPCM450_NUM_GPIO_IRQS; i++) { - int irq = fwnode_irq_get(child, i); + int irq; + irq = fwnode_irq_get(child, i); if (irq < 0) break; + if (!irq) + continue; girq->parents[i] = irq; girq->num_parents++; From e75729b2f63fbdbf776930de8b0eee0d43a68be6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 28 Sep 2022 13:20:18 -0700 Subject: [PATCH 303/401] pinctrl: st: stop abusing of_get_named_gpio() Pin descriptions for this chip only look like standard GPIO device tree descriptions, while in fact they contain additional data (in excess of number of cells specified in description of gpio controllers). They also refer to only pins/gpios belonging to the driver and not to arbitrary gpio in the system. Because we want to stop exporting OF-specific handlers from gpiolib-of, let's parse the pin reference ourself instead of trying to call of_get_named_gpio(). Signed-off-by: Dmitry Torokhov Tested-by: Patrice Chotard Reviewed-by: Patrice Chotard Link: https://lore.kernel.org/r/YzSsgoVoJn4+mSpv@google.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-st.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 0fea71fd9a00..cf7f9cbe6044 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -12,7 +12,6 @@ #include #include #include -#include /* of_get_named_gpio() */ #include #include #include @@ -1162,6 +1161,31 @@ static void st_parse_syscfgs(struct st_pinctrl *info, int bank, return; } +static int st_pctl_dt_calculate_pin(struct st_pinctrl *info, + phandle bank, unsigned int offset) +{ + struct device_node *np; + struct gpio_chip *chip; + int retval = -EINVAL; + int i; + + np = of_find_node_by_phandle(bank); + if (!np) + return -EINVAL; + + for (i = 0; i < info->nbanks; i++) { + chip = &info->banks[i].gpio_chip; + if (chip->of_node == np) { + if (offset < chip->ngpio) + retval = chip->base + offset; + break; + } + } + + of_node_put(np); + return retval; +} + /* * Each pin is represented in of the below forms. * @@ -1175,6 +1199,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np, struct device *dev = info->dev; struct st_pinconf *conf; struct device_node *pins; + phandle bank; + unsigned int offset; int i = 0, npins = 0, nr_props, ret = 0; pins = of_get_child_by_name(np, "st,pins"); @@ -1214,9 +1240,9 @@ static int st_pctl_dt_parse_groups(struct device_node *np, conf = &grp->pin_conf[i]; /* bank & offset */ - be32_to_cpup(list++); - be32_to_cpup(list++); - conf->pin = of_get_named_gpio(pins, pp->name, 0); + bank = be32_to_cpup(list++); + offset = be32_to_cpup(list++); + conf->pin = st_pctl_dt_calculate_pin(info, bank, offset); conf->name = pp->name; grp->pins[i] = conf->pin; /* mux */ From 448921706bdd1758ac63c07185c5a4713278d6f8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 26 Sep 2022 22:47:24 +0200 Subject: [PATCH 304/401] dt-bindings: pinctrl: st,stm32: Document gpio-line-names Document gpio-line-names property as valid property. This fixes dtbs_check warnings when building current Linux DTs: " arch/arm/boot/dts/stm32mp153c-dhcom-drc02.dtb: pinctrl@50002000: gpio@50009000: 'gpio-line-names' does not match any of the regexes: 'pinctrl-[0-9]+' " Signed-off-by: Marek Vasut Acked-by: Rob Herring Link: https://lore.kernel.org/r/20220926204724.381760-1-marex@denx.de Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml index 53c952d93ea2..06229d93c24c 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -71,6 +71,7 @@ patternProperties: maxItems: 1 resets: maxItems: 1 + gpio-line-names: true gpio-ranges: minItems: 1 maxItems: 16 From 140bb02315e78923dc0ecd7d3c7f021c0167a817 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 26 Sep 2022 22:47:35 +0200 Subject: [PATCH 305/401] dt-bindings: pinctrl: st,stm32: Document gpio-hog pattern property Document gpio-hog pattern property and its subnodes. This fixes dtbs_check warnings when building current Linux DTs: " arch/arm/boot/dts/stm32mp153c-dhcom-drc02.dtb: pinctrl@50002000: gpio@50003000: 'rs485-rx-en-hog' does not match any of the regexes: 'pinctrl-[0-9]+' " Signed-off-by: Marek Vasut Acked-by: Rob Herring Link: https://lore.kernel.org/r/20220926204735.381779-1-marex@denx.de Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml index 06229d93c24c..12598e036287 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -107,6 +107,12 @@ patternProperties: minimum: 0 maximum: 11 + patternProperties: + "^(.+-hog(-[0-9]+)?)$": + type: object + required: + - gpio-hog + required: - gpio-controller - '#gpio-cells' From 5197b707d68ad75a165db743ac1151ea3407c1eb Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 26 Sep 2022 22:47:52 +0200 Subject: [PATCH 306/401] dt-bindings: pinctrl: st,stm32: Document interrupt-controller property Document interrupt-controller property and its interrupt-cells. This fixes dtbs_check warnings when building current Linux DTs: " arch/arm/boot/dts/stm32mp153c-dhcom-drc02.dtb: pinctrl@50002000: gpio@5000a000: '#interrupt-cells', 'interrupt-controller' do not match any of the regexes: 'pinctrl-[0-9]+' " Signed-off-by: Marek Vasut Acked-by: Rob Herring Link: https://lore.kernel.org/r/20220926204752.381798-1-marex@denx.de Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml index 12598e036287..9d59208d83c1 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -64,6 +64,9 @@ patternProperties: gpio-controller: true '#gpio-cells': const: 2 + interrupt-controller: true + '#interrupt-cells': + const: 2 reg: maxItems: 1 From ba7fdf88e98acadc00c56e1272d022564f7ac721 Mon Sep 17 00:00:00 2001 From: Jianlong Huang Date: Fri, 30 Sep 2022 14:08:19 +0800 Subject: [PATCH 307/401] pinctrl: Create subdirectory for StarFive drivers Move the StarFive JH7100 pinctrl driver to a new subdirectory in preparation for adding more StarFive pinctrl drivers. No functional change. Signed-off-by: Jianlong Huang Signed-off-by: Hal Feng Link: https://lore.kernel.org/r/20220930060819.5320-1-hal.feng@linux.starfivetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 18 +----------------- drivers/pinctrl/Makefile | 2 +- drivers/pinctrl/starfive/Kconfig | 18 ++++++++++++++++++ drivers/pinctrl/starfive/Makefile | 3 +++ .../pinctrl/{ => starfive}/pinctrl-starfive.c | 8 ++++---- 5 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 drivers/pinctrl/starfive/Kconfig create mode 100644 drivers/pinctrl/starfive/Makefile rename drivers/pinctrl/{ => starfive}/pinctrl-starfive.c (99%) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index da87f2dc358b..287420cfc850 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -431,23 +431,6 @@ config PINCTRL_ST select PINCONF select GPIOLIB_IRQCHIP -config PINCTRL_STARFIVE - tristate "Pinctrl and GPIO driver for the StarFive JH7100 SoC" - depends on SOC_STARFIVE || COMPILE_TEST - depends on OF - default SOC_STARFIVE - select GENERIC_PINCTRL_GROUPS - select GENERIC_PINMUX_FUNCTIONS - select GENERIC_PINCONF - select GPIOLIB - select GPIOLIB_IRQCHIP - select OF_GPIO - help - Say yes here to support pin control on the StarFive JH7100 SoC. - This also provides an interface to the GPIO pins not used by other - peripherals supporting inputs, outputs, configuring pull-up/pull-down - and interrupts on input changes. - config PINCTRL_STMFX tristate "STMicroelectronics STMFX GPIO expander pinctrl driver" depends on I2C @@ -545,6 +528,7 @@ source "drivers/pinctrl/renesas/Kconfig" source "drivers/pinctrl/samsung/Kconfig" source "drivers/pinctrl/spear/Kconfig" source "drivers/pinctrl/sprd/Kconfig" +source "drivers/pinctrl/starfive/Kconfig" source "drivers/pinctrl/stm32/Kconfig" source "drivers/pinctrl/sunplus/Kconfig" source "drivers/pinctrl/sunxi/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 7188dab7eec8..89bfa01b5231 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -44,7 +44,6 @@ obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o -obj-$(CONFIG_PINCTRL_STARFIVE) += pinctrl-starfive.o obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o @@ -71,6 +70,7 @@ obj-$(CONFIG_PINCTRL_RENESAS) += renesas/ obj-$(CONFIG_PINCTRL_SAMSUNG) += samsung/ obj-$(CONFIG_PINCTRL_SPEAR) += spear/ obj-y += sprd/ +obj-$(CONFIG_SOC_STARFIVE) += starfive/ obj-$(CONFIG_PINCTRL_STM32) += stm32/ obj-y += sunplus/ obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/ diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig new file mode 100644 index 000000000000..13c3275a5724 --- /dev/null +++ b/drivers/pinctrl/starfive/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config PINCTRL_STARFIVE + tristate "Pinctrl and GPIO driver for the StarFive JH7100 SoC" + depends on SOC_STARFIVE || COMPILE_TEST + depends on OF + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + select GENERIC_PINCONF + select GPIOLIB + select GPIOLIB_IRQCHIP + select OF_GPIO + default SOC_STARFIVE + help + Say yes here to support pin control on the StarFive JH7100 SoC. + This also provides an interface to the GPIO pins not used by other + peripherals supporting inputs, outputs, configuring pull-up/pull-down + and interrupts on input changes. diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile new file mode 100644 index 000000000000..4c96e2f86292 --- /dev/null +++ b/drivers/pinctrl/starfive/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_PINCTRL_STARFIVE) += pinctrl-starfive.o diff --git a/drivers/pinctrl/pinctrl-starfive.c b/drivers/pinctrl/starfive/pinctrl-starfive.c similarity index 99% rename from drivers/pinctrl/pinctrl-starfive.c rename to drivers/pinctrl/starfive/pinctrl-starfive.c index 3eb40e230d98..74a084740e8c 100644 --- a/drivers/pinctrl/pinctrl-starfive.c +++ b/drivers/pinctrl/starfive/pinctrl-starfive.c @@ -22,10 +22,10 @@ #include -#include "core.h" -#include "pinctrl-utils.h" -#include "pinmux.h" -#include "pinconf.h" +#include "../core.h" +#include "../pinctrl-utils.h" +#include "../pinmux.h" +#include "../pinconf.h" #define DRIVER_NAME "pinctrl-starfive" From ba99b756da178aa8c608c4499a91074466050c10 Mon Sep 17 00:00:00 2001 From: Jianlong Huang Date: Fri, 30 Sep 2022 14:14:04 +0800 Subject: [PATCH 308/401] pinctrl: starfive: Rename "pinctrl-starfive" to "pinctrl-starfive-jh7100" Add the SoC name to make it more clear. Also the next generation StarFive SoCs will use "pinctrl-starfive" as the core of StarFive pinctrl driver. No functional change. Signed-off-by: Jianlong Huang Signed-off-by: Hal Feng Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20220930061404.5418-1-hal.feng@linux.starfivetech.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/starfive,jh7100-pinctrl.yaml | 2 +- arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts | 2 +- drivers/pinctrl/starfive/Kconfig | 2 +- drivers/pinctrl/starfive/Makefile | 2 +- .../{pinctrl-starfive.c => pinctrl-starfive-jh7100.c} | 2 +- .../{pinctrl-starfive.h => pinctrl-starfive-jh7100.h} | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) rename drivers/pinctrl/starfive/{pinctrl-starfive.c => pinctrl-starfive-jh7100.c} (99%) rename include/dt-bindings/pinctrl/{pinctrl-starfive.h => pinctrl-starfive-jh7100.h} (98%) diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml index 92963604422f..a6140dddd39a 100644 --- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml @@ -165,7 +165,7 @@ examples: - | #include #include - #include + #include soc { #address-cells = <2>; diff --git a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts index c9af67f7a0d2..f7a230110512 100644 --- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts +++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts @@ -8,7 +8,7 @@ #include "jh7100.dtsi" #include #include -#include +#include / { model = "BeagleV Starlight Beta"; diff --git a/drivers/pinctrl/starfive/Kconfig b/drivers/pinctrl/starfive/Kconfig index 13c3275a5724..55c514e622f9 100644 --- a/drivers/pinctrl/starfive/Kconfig +++ b/drivers/pinctrl/starfive/Kconfig @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -config PINCTRL_STARFIVE +config PINCTRL_STARFIVE_JH7100 tristate "Pinctrl and GPIO driver for the StarFive JH7100 SoC" depends on SOC_STARFIVE || COMPILE_TEST depends on OF diff --git a/drivers/pinctrl/starfive/Makefile b/drivers/pinctrl/starfive/Makefile index 4c96e2f86292..0293f26a0a99 100644 --- a/drivers/pinctrl/starfive/Makefile +++ b/drivers/pinctrl/starfive/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_PINCTRL_STARFIVE) += pinctrl-starfive.o +obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) += pinctrl-starfive-jh7100.o diff --git a/drivers/pinctrl/starfive/pinctrl-starfive.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c similarity index 99% rename from drivers/pinctrl/starfive/pinctrl-starfive.c rename to drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c index 74a084740e8c..5b544fb7f3d8 100644 --- a/drivers/pinctrl/starfive/pinctrl-starfive.c +++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include "../core.h" #include "../pinctrl-utils.h" diff --git a/include/dt-bindings/pinctrl/pinctrl-starfive.h b/include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h similarity index 98% rename from include/dt-bindings/pinctrl/pinctrl-starfive.h rename to include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h index de4f75c2c9e8..a200f546d078 100644 --- a/include/dt-bindings/pinctrl/pinctrl-starfive.h +++ b/include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h @@ -3,8 +3,8 @@ * Copyright (C) 2021 Emil Renner Berthing */ -#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_H__ -#define __DT_BINDINGS_PINCTRL_STARFIVE_H__ +#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_JH7100_H__ +#define __DT_BINDINGS_PINCTRL_STARFIVE_JH7100_H__ #define PAD_GPIO_OFFSET 0 #define PAD_FUNC_SHARE_OFFSET 64 @@ -272,4 +272,4 @@ #define GPI_NONE 0xff -#endif /* __DT_BINDINGS_PINCTRL_STARFIVE_H__ */ +#endif /* __DT_BINDINGS_PINCTRL_STARFIVE_JH7100_H__ */ From 280dfeae56e6fbfff21cfece356379e318ae10fe Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Tue, 30 Aug 2022 20:13:23 +0800 Subject: [PATCH 309/401] f2fs: return the tmp_ptr directly in __bitmap_ptr Just return tmp_ptr here, it's no need to dereference checkpoint pointer again. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 088c3d1574b8..0cc2f7aa45db 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2529,7 +2529,7 @@ static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) if (__cp_payload(sbi) > 0) { if (flag == NAT_BITMAP) - return &ckpt->sit_nat_version_bitmap; + return tmp_ptr; else return (unsigned char *)ckpt + F2FS_BLKSIZE; } else { From 173cdf2c32b4b02474006d87648383244c0a6db9 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Tue, 30 Aug 2022 14:55:15 +0800 Subject: [PATCH 310/401] f2fs: use COMPRESS_MAPPING to get compress cache mapping Just use the defined COMPRESS_MAPPING to get compress cache mapping instaed of direct accessing name. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 730256732a9e..6baaff4c52ba 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1901,7 +1901,7 @@ bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page, void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino) { - struct address_space *mapping = sbi->compress_inode->i_mapping; + struct address_space *mapping = COMPRESS_MAPPING(sbi); struct folio_batch fbatch; pgoff_t index = 0; pgoff_t end = MAX_BLKADDR(sbi); From 9b7eadd9bd3a0cc24533a23d83c46430a0ea60ff Mon Sep 17 00:00:00 2001 From: Shuqi Zhang Date: Wed, 31 Aug 2022 10:24:40 +0800 Subject: [PATCH 311/401] f2fs: fix wrong dirty page count when race between mmap and fallocate. This is a BUG_ON issue as follows when running xfstest-generic-503: WARNING: CPU: 21 PID: 1385 at fs/f2fs/inode.c:762 f2fs_evict_inode+0x847/0xaa0 Modules linked in: CPU: 21 PID: 1385 Comm: umount Not tainted 5.19.0-rc5+ #73 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-4.fc34 04/01/2014 Call Trace: evict+0x129/0x2d0 dispose_list+0x4f/0xb0 evict_inodes+0x204/0x230 generic_shutdown_super+0x5b/0x1e0 kill_block_super+0x29/0x80 kill_f2fs_super+0xe6/0x140 deactivate_locked_super+0x44/0xc0 deactivate_super+0x79/0x90 cleanup_mnt+0x114/0x1a0 __cleanup_mnt+0x16/0x20 task_work_run+0x98/0x100 exit_to_user_mode_prepare+0x3d0/0x3e0 syscall_exit_to_user_mode+0x12/0x30 do_syscall_64+0x42/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Function flow analysis when BUG occurs: f2fs_fallocate mmap do_page_fault pte_spinlock // ---lock_pte do_wp_page wp_page_shared pte_unmap_unlock // unlock_pte do_page_mkwrite f2fs_vm_page_mkwrite down_read(invalidate_lock) lock_page if (PageMappedToDisk(page)) goto out; // set_page_dirty --NOT RUN out: up_read(invalidate_lock); finish_mkwrite_fault // unlock_pte f2fs_collapse_range down_write(i_mmap_sem) truncate_pagecache unmap_mapping_pages i_mmap_lock_write // down_write(i_mmap_rwsem) ...... zap_pte_range pte_offset_map_lock // ---lock_pte set_page_dirty f2fs_dirty_data_folio if (!folio_test_dirty(folio)) { fault_dirty_shared_page set_page_dirty f2fs_dirty_data_folio if (!folio_test_dirty(folio)) { filemap_dirty_folio f2fs_update_dirty_folio // ++ } unlock_page filemap_dirty_folio f2fs_update_dirty_folio // page count++ } pte_unmap_unlock // --unlock_pte i_mmap_unlock_write // up_write(i_mmap_rwsem) truncate_inode_pages up_write(i_mmap_sem) When race happens between mmap-do_page_fault-wp_page_shared and fallocate-truncate_pagecache-zap_pte_range, the zap_pte_range calls function set_page_dirty without page lock. Besides, though truncate_pagecache has immap and pte lock, wp_page_shared calls fault_dirty_shared_page without any. In this case, two threads race in f2fs_dirty_data_folio function. Page is set to dirty only ONCE, but the count is added TWICE by calling filemap_dirty_folio. Thus the count of dirty page cannot accord with the real dirty pages. Following is the solution to in case of race happens without any lock. Since folio_test_set_dirty in filemap_dirty_folio is atomic, judge return value will not be at risk of race. Signed-off-by: Shuqi Zhang Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 3 +-- fs/f2fs/data.c | 3 +-- fs/f2fs/node.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 7bf1feb5ac78..cf315e3d244c 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -449,8 +449,7 @@ static bool f2fs_dirty_meta_folio(struct address_space *mapping, if (!folio_test_uptodate(folio)) folio_mark_uptodate(folio); - if (!folio_test_dirty(folio)) { - filemap_dirty_folio(mapping, folio); + if (filemap_dirty_folio(mapping, folio)) { inc_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_META); set_page_private_reference(&folio->page); return true; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 0869fbbb5516..87524d3dce22 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3697,8 +3697,7 @@ static bool f2fs_dirty_data_folio(struct address_space *mapping, folio_mark_uptodate(folio); BUG_ON(folio_test_swapcache(folio)); - if (!folio_test_dirty(folio)) { - filemap_dirty_folio(mapping, folio); + if (filemap_dirty_folio(mapping, folio)) { f2fs_update_dirty_folio(inode, folio); return true; } diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 2484285be3ad..23291f1575d3 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -2147,8 +2147,7 @@ static bool f2fs_dirty_node_folio(struct address_space *mapping, if (IS_INODE(&folio->page)) f2fs_inode_chksum_set(F2FS_M_SB(mapping), &folio->page); #endif - if (!folio_test_dirty(folio)) { - filemap_dirty_folio(mapping, folio); + if (filemap_dirty_folio(mapping, folio)) { inc_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_NODES); set_page_private_reference(&folio->page); return true; From d382e36970ecf8242921400db2afde15fb6ed49e Mon Sep 17 00:00:00 2001 From: Yonggil Song Date: Fri, 2 Sep 2022 11:07:49 +0900 Subject: [PATCH 312/401] f2fs: fix typo Fix typo in f2fs.h Detected by Jaeyoon Choi Signed-off-by: Yonggil Song Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 0cc2f7aa45db..d7bb7d4f9434 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -274,7 +274,7 @@ enum { ORPHAN_INO, /* for orphan ino list */ APPEND_INO, /* for append ino list */ UPDATE_INO, /* for update ino list */ - TRANS_DIR_INO, /* for trasactions dir ino list */ + TRANS_DIR_INO, /* for transactions dir ino list */ FLUSH_INO, /* for multiple device flushing */ MAX_INO_ENTRY, /* max. list */ }; From 049ea86cb5c7212a6e7e617a67fe686f9b0b0669 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Wed, 31 Aug 2022 17:48:15 +0800 Subject: [PATCH 313/401] f2fs: add static init_idisk_time function to reduce the code We can use a inner function to init the disk time of f2fs_inode_info for cleaning redundant code. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/inode.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 6d11c365d7b4..cde0a3dc80c3 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -333,6 +333,16 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page) return true; } +static void init_idisk_time(struct inode *inode) +{ + struct f2fs_inode_info *fi = F2FS_I(inode); + + fi->i_disk_time[0] = inode->i_atime; + fi->i_disk_time[1] = inode->i_ctime; + fi->i_disk_time[2] = inode->i_mtime; + fi->i_disk_time[3] = fi->i_crtime; +} + static int do_read_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); @@ -465,10 +475,7 @@ static int do_read_inode(struct inode *inode) } } - fi->i_disk_time[0] = inode->i_atime; - fi->i_disk_time[1] = inode->i_ctime; - fi->i_disk_time[2] = inode->i_mtime; - fi->i_disk_time[3] = fi->i_crtime; + init_idisk_time(inode); f2fs_put_page(node_page, 1); stat_inc_inline_xattr(inode); @@ -676,11 +683,7 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page) if (inode->i_nlink == 0) clear_page_private_inline(node_page); - F2FS_I(inode)->i_disk_time[0] = inode->i_atime; - F2FS_I(inode)->i_disk_time[1] = inode->i_ctime; - F2FS_I(inode)->i_disk_time[2] = inode->i_mtime; - F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime; - + init_idisk_time(inode); #ifdef CONFIG_F2FS_CHECK_FS f2fs_inode_chksum_set(F2FS_I_SB(inode), node_page); #endif From 9df6d6f9be4754da96d3c91ec518ed974e6b81e7 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Thu, 1 Sep 2022 15:19:37 +0800 Subject: [PATCH 314/401] f2fs: remove redundant check in f2fs_sanity_check_cluster It have checked "compressed" at the entry of f2fs_sanity_check_cluster, just remove the redundant check for better performance here. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/compress.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 6baaff4c52ba..c16bab5bd600 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -912,17 +912,15 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn) reason = "[C|*|C|*]"; goto out; } - if (compressed) { - if (!__is_valid_data_blkaddr(blkaddr)) { - if (!cluster_end) - cluster_end = i; - continue; - } - /* [COMPR_ADDR, NULL_ADDR or NEW_ADDR, valid_blkaddr] */ - if (cluster_end) { - reason = "[C|N|N|V]"; - goto out; - } + if (!__is_valid_data_blkaddr(blkaddr)) { + if (!cluster_end) + cluster_end = i; + continue; + } + /* [COMPR_ADDR, NULL_ADDR or NEW_ADDR, valid_blkaddr] */ + if (cluster_end) { + reason = "[C|N|N|V]"; + goto out; } } return false; From 07725adc55c0a414c10acb5c8c86cea34b95ddef Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Mon, 5 Sep 2022 12:59:17 +0800 Subject: [PATCH 315/401] f2fs: fix race condition on setting FI_NO_EXTENT flag The following scenarios exist. process A: process B: ->f2fs_drop_extent_tree ->f2fs_update_extent_cache_range ->f2fs_update_extent_tree_range ->write_lock ->set_inode_flag ->is_inode_flag_set ->__free_extent_tree // Shouldn't // have been // cleaned up // here ->write_lock In this case, the "FI_NO_EXTENT" flag is set between f2fs_update_extent_tree_range and is_inode_flag_set by other process. it leads to clearing the whole exten tree which should not have happened. And we fix it by move the setting it to the range of write_lock. Fixes:5f281fab9b9a3 ("f2fs: disable extent_cache for fcollapse/finsert inodes") Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/extent_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 866e72b29bd5..761fd42c93f2 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -804,9 +804,8 @@ void f2fs_drop_extent_tree(struct inode *inode) if (!f2fs_may_extent_tree(inode)) return; - set_inode_flag(inode, FI_NO_EXTENT); - write_lock(&et->lock); + set_inode_flag(inode, FI_NO_EXTENT); __free_extent_tree(sbi, et); if (et->largest.len) { et->largest.len = 0; From f3b23c785aa5d1920f479533f1d7361c2feceea5 Mon Sep 17 00:00:00 2001 From: Weichao Guo Date: Wed, 7 Sep 2022 10:38:48 +0800 Subject: [PATCH 316/401] f2fs: let FI_OPU_WRITE override FADVISE_COLD_BIT Cold files may be fragmented due to SSR, defragment is needed as sequential reads are dominant scenarios of these files. FI_OPU_WRITE should override FADVISE_COLD_BIT to avoid defragment fails. Signed-off-by: Weichao Guo Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 87524d3dce22..a737eedef779 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2543,7 +2543,7 @@ bool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio) return true; /* if this is cold file, we should overwrite to avoid fragmentation */ - if (file_is_cold(inode)) + if (file_is_cold(inode) && !is_inode_flag_set(inode, FI_OPU_WRITE)) return true; return check_inplace_update_policy(inode, fio); From 0ef4ca04a3f9223ff8bc440041c524b2123e09a3 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 13 Sep 2022 10:08:41 +0800 Subject: [PATCH 317/401] f2fs: fix to do sanity check on destination blkaddr during recovery As Wenqing Liu reported in bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216456 loop5: detected capacity change from 0 to 131072 F2FS-fs (loop5): recover_inode: ino = 6, name = hln, inline = 1 F2FS-fs (loop5): recover_data: ino = 6 (i_size: recover) err = 0 F2FS-fs (loop5): recover_inode: ino = 6, name = hln, inline = 1 F2FS-fs (loop5): recover_data: ino = 6 (i_size: recover) err = 0 F2FS-fs (loop5): recover_inode: ino = 6, name = hln, inline = 1 F2FS-fs (loop5): recover_data: ino = 6 (i_size: recover) err = 0 F2FS-fs (loop5): Bitmap was wrongly set, blk:5634 ------------[ cut here ]------------ WARNING: CPU: 3 PID: 1013 at fs/f2fs/segment.c:2198 RIP: 0010:update_sit_entry+0xa55/0x10b0 [f2fs] Call Trace: f2fs_do_replace_block+0xa98/0x1890 [f2fs] f2fs_replace_block+0xeb/0x180 [f2fs] recover_data+0x1a69/0x6ae0 [f2fs] f2fs_recover_fsync_data+0x120d/0x1fc0 [f2fs] f2fs_fill_super+0x4665/0x61e0 [f2fs] mount_bdev+0x2cf/0x3b0 legacy_get_tree+0xed/0x1d0 vfs_get_tree+0x81/0x2b0 path_mount+0x47e/0x19d0 do_mount+0xce/0xf0 __x64_sys_mount+0x12c/0x1a0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd If we enable CONFIG_F2FS_CHECK_FS config, it will trigger a kernel panic instead of warning. The root cause is: in fuzzed image, SIT table is inconsistent with inode mapping table, result in triggering such warning during SIT table update. This patch introduces a new flag DATA_GENERIC_ENHANCE_UPDATE, w/ this flag, data block recovery flow can check destination blkaddr's validation in SIT table, and skip f2fs_replace_block() to avoid inconsistent status. Cc: stable@vger.kernel.org Reported-by: Wenqing Liu Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 10 +++++++++- fs/f2fs/f2fs.h | 4 ++++ fs/f2fs/recovery.c | 8 ++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index cf315e3d244c..c3119e4c890c 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -140,7 +140,7 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr, unsigned int segno, offset; bool exist; - if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ) + if (type == DATA_GENERIC) return true; segno = GET_SEGNO(sbi, blkaddr); @@ -148,6 +148,13 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr, se = get_seg_entry(sbi, segno); exist = f2fs_test_bit(offset, se->cur_valid_map); + if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) { + f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d", + blkaddr, exist); + set_sbi_flag(sbi, SBI_NEED_FSCK); + return exist; + } + if (!exist && type == DATA_GENERIC_ENHANCE) { f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d", blkaddr, exist); @@ -185,6 +192,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, case DATA_GENERIC: case DATA_GENERIC_ENHANCE: case DATA_GENERIC_ENHANCE_READ: + case DATA_GENERIC_ENHANCE_UPDATE: if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || blkaddr < MAIN_BLKADDR(sbi))) { f2fs_warn(sbi, "access invalid blkaddr:%u", diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d7bb7d4f9434..4636e14bcbf3 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -266,6 +266,10 @@ enum { * condition of read on truncated area * by extent_cache */ + DATA_GENERIC_ENHANCE_UPDATE, /* + * strong check on range and segment + * bitmap for update case + */ META_GENERIC, }; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index dcd0a1e35095..8326003e6918 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -698,6 +698,14 @@ retry_prev: goto err; } + if (f2fs_is_valid_blkaddr(sbi, dest, + DATA_GENERIC_ENHANCE_UPDATE)) { + f2fs_err(sbi, "Inconsistent dest blkaddr:%u, ino:%lu, ofs:%u", + dest, inode->i_ino, dn.ofs_in_node); + err = -EFSCORRUPTED; + goto err; + } + /* write dummy data page */ f2fs_replace_block(sbi, &dn, src, dest, ni.version, false, false); From 1e8a9191ccc286bbbfc1f9dccd31ac3bc9ec8a3f Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Fri, 9 Sep 2022 11:17:44 +0200 Subject: [PATCH 318/401] f2fs: port to vfs{g,u}id_t and associated helpers A while ago we introduced a dedicated vfs{g,u}id_t type in commit 1e5267cd0895 ("mnt_idmapping: add vfs{g,u}id_t"). We already switched over a good part of the VFS. Ultimately we will remove all legacy idmapped mount helpers that operate only on k{g,u}id_t in favor of the new type safe helpers that operate on vfs{g,u}id_t. Cc: Seth Forshee (Digital Ocean) Cc: Christoph Hellwig Cc: Jaegeuk Kim Cc: Chao Yu Cc: linux-f2fs-devel@lists.sourceforge.net Signed-off-by: Christian Brauner (Microsoft) Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/acl.c | 2 +- fs/f2fs/file.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index eaa240b21f07..5bbc44a5216e 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -219,7 +219,7 @@ static int f2fs_acl_update_mode(struct user_namespace *mnt_userns, return error; if (error == 0) *acl = NULL; - if (!in_group_p(i_gid_into_mnt(mnt_userns, inode)) && + if (!vfsgid_in_group_p(i_gid_into_vfsgid(mnt_userns, inode)) && !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) mode &= ~S_ISGID; *mode_p = mode; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 771f1f7f3690..5efe0e4a725a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -871,9 +871,10 @@ static void __setattr_copy(struct user_namespace *mnt_userns, inode->i_ctime = attr->ia_ctime; if (ia_valid & ATTR_MODE) { umode_t mode = attr->ia_mode; - kgid_t kgid = i_gid_into_mnt(mnt_userns, inode); + vfsgid_t vfsgid = i_gid_into_vfsgid(mnt_userns, inode); - if (!in_group_p(kgid) && !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) + if (!vfsgid_in_group_p(vfsgid) && + !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) mode &= ~S_ISGID; set_acl_inode(inode, mode); } From c6ad7fd16657ebd34a87a97d9588195aae87597d Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 14 Sep 2022 19:51:51 +0800 Subject: [PATCH 319/401] f2fs: fix to do sanity check on summary info As Wenqing Liu reported in bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216456 BUG: KASAN: use-after-free in recover_data+0x63ae/0x6ae0 [f2fs] Read of size 4 at addr ffff8881464dcd80 by task mount/1013 CPU: 3 PID: 1013 Comm: mount Tainted: G W 6.0.0-rc4 #1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 Call Trace: dump_stack_lvl+0x45/0x5e print_report.cold+0xf3/0x68d kasan_report+0xa8/0x130 recover_data+0x63ae/0x6ae0 [f2fs] f2fs_recover_fsync_data+0x120d/0x1fc0 [f2fs] f2fs_fill_super+0x4665/0x61e0 [f2fs] mount_bdev+0x2cf/0x3b0 legacy_get_tree+0xed/0x1d0 vfs_get_tree+0x81/0x2b0 path_mount+0x47e/0x19d0 do_mount+0xce/0xf0 __x64_sys_mount+0x12c/0x1a0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd The root cause is: in fuzzed image, SSA table is corrupted: ofs_in_node is larger than ADDRS_PER_PAGE(), result in out-of-range access on 4k-size page. - recover_data - do_recover_data - check_index_in_prev_nodes - f2fs_data_blkaddr This patch adds sanity check on summary info in recovery and GC flow in where the flows rely on them. After patch: [ 29.310883] F2FS-fs (loop0): Inconsistent ofs_in_node:65286 in summary, ino:0, nid:6, max:1018 Cc: stable@vger.kernel.org Reported-by: Wenqing Liu Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 10 +++++++++- fs/f2fs/recovery.c | 15 ++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index fd400d148afb..3a820e5cdaee 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1078,7 +1078,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, { struct page *node_page; nid_t nid; - unsigned int ofs_in_node; + unsigned int ofs_in_node, max_addrs; block_t source_blkaddr; nid = le32_to_cpu(sum->nid); @@ -1104,6 +1104,14 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, return false; } + max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE : + DEF_ADDRS_PER_BLOCK; + if (ofs_in_node >= max_addrs) { + f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u", + ofs_in_node, dni->ino, dni->nid, max_addrs); + return false; + } + *nofs = ofs_of_node(node_page); source_blkaddr = data_blkaddr(NULL, node_page, ofs_in_node); f2fs_put_page(node_page, 1); diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 8326003e6918..5c9facec98f6 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -474,7 +474,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, struct dnode_of_data tdn = *dn; nid_t ino, nid; struct inode *inode; - unsigned int offset; + unsigned int offset, ofs_in_node, max_addrs; block_t bidx; int i; @@ -501,15 +501,24 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, got_it: /* Use the locked dnode page and inode */ nid = le32_to_cpu(sum.nid); + ofs_in_node = le16_to_cpu(sum.ofs_in_node); + + max_addrs = ADDRS_PER_PAGE(dn->node_page, dn->inode); + if (ofs_in_node >= max_addrs) { + f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%lu, nid:%u, max:%u", + ofs_in_node, dn->inode->i_ino, nid, max_addrs); + return -EFSCORRUPTED; + } + if (dn->inode->i_ino == nid) { tdn.nid = nid; if (!dn->inode_page_locked) lock_page(dn->inode_page); tdn.node_page = dn->inode_page; - tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node); + tdn.ofs_in_node = ofs_in_node; goto truncate_out; } else if (dn->nid == nid) { - tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node); + tdn.ofs_in_node = ofs_in_node; goto truncate_out; } From a834aa3ec95b0d1a465854b27016eec1af2f0e1f Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Mon, 19 Sep 2022 19:57:09 +0800 Subject: [PATCH 320/401] f2fs: add "c_len" into trace_f2fs_update_extent_tree_range for compressed file The trace_f2fs_update_extent_tree_range could not record compressed block length in the cluster of compress file and we just add it. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/extent_cache.c | 4 ++-- include/trace/events/f2fs.h | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 761fd42c93f2..746abfda3b66 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -544,7 +544,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode, if (!et) return; - trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, len); + trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, len, 0); write_lock(&et->lock); @@ -675,7 +675,7 @@ void f2fs_update_extent_tree_range_compressed(struct inode *inode, struct rb_node **insert_p = NULL, *insert_parent = NULL; bool leftmost = false; - trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, llen); + trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, llen, c_len); /* it is safe here to check FI_NO_EXTENT w/o et->lock in ro image */ if (is_inode_flag_set(inode, FI_NO_EXTENT)) diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index b262985f0c3a..c6b372401c27 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -1578,9 +1578,10 @@ TRACE_EVENT_CONDITION(f2fs_lookup_extent_tree_end, TRACE_EVENT(f2fs_update_extent_tree_range, TP_PROTO(struct inode *inode, unsigned int pgofs, block_t blkaddr, - unsigned int len), + unsigned int len, + unsigned int c_len), - TP_ARGS(inode, pgofs, blkaddr, len), + TP_ARGS(inode, pgofs, blkaddr, len, c_len), TP_STRUCT__entry( __field(dev_t, dev) @@ -1588,6 +1589,7 @@ TRACE_EVENT(f2fs_update_extent_tree_range, __field(unsigned int, pgofs) __field(u32, blk) __field(unsigned int, len) + __field(unsigned int, c_len) ), TP_fast_assign( @@ -1596,14 +1598,17 @@ TRACE_EVENT(f2fs_update_extent_tree_range, __entry->pgofs = pgofs; __entry->blk = blkaddr; __entry->len = len; + __entry->c_len = c_len; ), TP_printk("dev = (%d,%d), ino = %lu, pgofs = %u, " - "blkaddr = %u, len = %u", + "blkaddr = %u, len = %u, " + "c_len = %u", show_dev_ino(__entry), __entry->pgofs, __entry->blk, - __entry->len) + __entry->len, + __entry->c_len) ); TRACE_EVENT(f2fs_shrink_extent_tree, From 544b53dadc208278fd0796f2c22ea24a3fe16564 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Wed, 14 Sep 2022 09:33:22 +0800 Subject: [PATCH 321/401] f2fs: code clean and fix a type error ERROR: code indent should use tabs where possible ERROR: spaces required around that ':' ERROR: incorrect tab Found serveral code type errors when review the code and fix it. There is no function change. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 +- fs/f2fs/debug.c | 2 +- fs/f2fs/extent_cache.c | 2 +- fs/f2fs/file.c | 2 +- fs/f2fs/node.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a737eedef779..b90f5f39da78 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -723,7 +723,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) wbc_account_cgroup_owner(fio->io_wbc, page, PAGE_SIZE); inc_page_count(fio->sbi, is_read_io(fio->op) ? - __read_io_type(page): WB_DATA_TYPE(fio->page)); + __read_io_type(page) : WB_DATA_TYPE(fio->page)); __submit_bio(fio->sbi, bio, fio->type); return 0; diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index c01471573977..29cf5b6b2341 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -347,7 +347,7 @@ static int stat_show(struct seq_file *s, void *v) seq_printf(s, "\n=====[ partition info(%pg). #%d, %s, CP: %s]=====\n", si->sbi->sb->s_bdev, i++, - f2fs_readonly(si->sbi->sb) ? "RO": "RW", + f2fs_readonly(si->sbi->sb) ? "RO" : "RW", is_set_ckpt_flags(si->sbi, CP_DISABLED_FLAG) ? "Disabled" : (f2fs_cp_error(si->sbi) ? "Error" : "Good")); if (si->sbi->s_flag) { diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 746abfda3b66..932c070173b9 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -583,7 +583,7 @@ static void f2fs_update_extent_tree_range(struct inode *inode, org_end = dei.fofs + dei.len; f2fs_bug_on(sbi, pos >= org_end); - if (pos > dei.fofs && pos - dei.fofs >= F2FS_MIN_EXTENT_LEN) { + if (pos > dei.fofs && pos - dei.fofs >= F2FS_MIN_EXTENT_LEN) { en->ei.len = pos - en->ei.fofs; prev_en = en; parts = 1; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 5efe0e4a725a..4020f5e72a2c 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -4622,7 +4622,7 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) skip_write_trace: /* Do the actual write. */ ret = dio ? - f2fs_dio_write_iter(iocb, from, &may_need_sync): + f2fs_dio_write_iter(iocb, from, &may_need_sync) : f2fs_buffered_write_iter(iocb, from); if (trace_f2fs_datawrite_end_enabled()) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 23291f1575d3..9263bf5f10d3 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -585,7 +585,7 @@ retry: ne = nat_in_journal(journal, i); node_info_from_raw_nat(ni, &ne); } - up_read(&curseg->journal_rwsem); + up_read(&curseg->journal_rwsem); if (i >= 0) { f2fs_up_read(&nm_i->nat_tree_lock); goto cache; From d80afefb17e01aa0c46a8eebc01882e0ebd8b0f6 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 14 Sep 2022 21:28:46 +0800 Subject: [PATCH 322/401] f2fs: fix to account FS_CP_DATA_IO correctly f2fs_inode_info.cp_task was introduced for FS_CP_DATA_IO accounting since commit b0af6d491a6b ("f2fs: add app/fs io stat"). However, cp_task usage coverage has been increased due to below commits: commit 040d2bb318d1 ("f2fs: fix to avoid deadloop if data_flush is on") commit 186857c5a14a ("f2fs: fix potential recursive call when enabling data_flush") So that, if data_flush mountoption is on, when data flush was triggered from background, the IO from data flush will be accounted as checkpoint IO type incorrectly. In order to fix this issue, this patch splits cp_task into two: a) cp_task: used for IO accounting b) wb_task: used to avoid deadlock Fixes: 040d2bb318d1 ("f2fs: fix to avoid deadloop if data_flush is on") Fixes: 186857c5a14a ("f2fs: fix potential recursive call when enabling data_flush") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 13 +++++++++---- fs/f2fs/data.c | 4 ++-- fs/f2fs/f2fs.h | 4 +++- fs/f2fs/segment.c | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index c3119e4c890c..308b70812cbd 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1061,7 +1061,8 @@ void f2fs_remove_dirty_inode(struct inode *inode) spin_unlock(&sbi->inode_lock[type]); } -int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) +int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type, + bool from_cp) { struct list_head *head; struct inode *inode; @@ -1096,11 +1097,15 @@ retry: if (inode) { unsigned long cur_ino = inode->i_ino; - F2FS_I(inode)->cp_task = current; + if (from_cp) + F2FS_I(inode)->cp_task = current; + F2FS_I(inode)->wb_task = current; filemap_fdatawrite(inode->i_mapping); - F2FS_I(inode)->cp_task = NULL; + F2FS_I(inode)->wb_task = NULL; + if (from_cp) + F2FS_I(inode)->cp_task = NULL; iput(inode); /* We need to give cpu to another writers. */ @@ -1229,7 +1234,7 @@ retry_flush_dents: /* write all the dirty dentry pages */ if (get_pages(sbi, F2FS_DIRTY_DENTS)) { f2fs_unlock_all(sbi); - err = f2fs_sync_dirty_inodes(sbi, DIR_INODE); + err = f2fs_sync_dirty_inodes(sbi, DIR_INODE, true); if (err) return err; cond_resched(); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index b90f5f39da78..a45b6ab2e2a5 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2856,7 +2856,7 @@ out: } unlock_page(page); if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode) && - !F2FS_I(inode)->cp_task && allow_balance) + !F2FS_I(inode)->wb_task && allow_balance) f2fs_balance_fs(sbi, need_balance_fs); if (unlikely(f2fs_cp_error(sbi))) { @@ -3156,7 +3156,7 @@ static inline bool __should_serialize_io(struct inode *inode, struct writeback_control *wbc) { /* to avoid deadlock in path of data flush */ - if (F2FS_I(inode)->cp_task) + if (F2FS_I(inode)->wb_task) return false; if (!S_ISREG(inode->i_mode)) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4636e14bcbf3..c494c40b644b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -786,6 +786,7 @@ struct f2fs_inode_info { unsigned int clevel; /* maximum level of given file name */ struct task_struct *task; /* lookup and create consistency */ struct task_struct *cp_task; /* separate cp/wb IO stats*/ + struct task_struct *wb_task; /* indicate inode is in context of writeback */ nid_t i_xattr_nid; /* node id that contains xattrs */ loff_t last_disk_size; /* lastly written file size */ spinlock_t i_size_lock; /* protect last_disk_size */ @@ -3745,7 +3746,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi); int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi); void f2fs_update_dirty_folio(struct inode *inode, struct folio *folio); void f2fs_remove_dirty_inode(struct inode *inode); -int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type); +int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type, + bool from_cp); void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type); u64 f2fs_get_sectors_written(struct f2fs_sb_info *sbi); int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 460048f3c850..3f14c0a4fb89 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -476,7 +476,7 @@ do_sync: mutex_lock(&sbi->flush_lock); blk_start_plug(&plug); - f2fs_sync_dirty_inodes(sbi, FILE_INODE); + f2fs_sync_dirty_inodes(sbi, FILE_INODE, false); blk_finish_plug(&plug); mutex_unlock(&sbi->flush_lock); From fcc2d8cc96b2f6141bbbe5b1e8953db990794b44 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 13 Sep 2022 15:48:12 +0800 Subject: [PATCH 323/401] f2fs: fix to detect corrupted meta ino It is possible that ino of dirent or orphan inode is corrupted in a fuzzed image, occasionally, if corrupted ino is equal to meta ino: meta_ino, node_ino or compress_ino, caller of f2fs_iget() from below call paths will get meta inode directly, it's not allowed, let's add sanity check to detect such cases. case #1 - recover_dentry - __f2fs_find_entry - f2fs_iget_retry case #2 - recover_orphan_inode - f2fs_iget_retry Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/inode.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index cde0a3dc80c3..93ec216da3e1 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -487,6 +487,12 @@ static int do_read_inode(struct inode *inode) return 0; } +static bool is_meta_ino(struct f2fs_sb_info *sbi, unsigned int ino) +{ + return ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi) || + ino == F2FS_COMPRESS_INO(sbi); +} + struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) { struct f2fs_sb_info *sbi = F2FS_SB(sb); @@ -498,16 +504,21 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) { + if (is_meta_ino(sbi, ino)) { + f2fs_err(sbi, "inaccessible inode: %lu, run fsck to repair", ino); + set_sbi_flag(sbi, SBI_NEED_FSCK); + ret = -EFSCORRUPTED; + trace_f2fs_iget_exit(inode, ret); + iput(inode); + return ERR_PTR(ret); + } + trace_f2fs_iget(inode); return inode; } - if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi)) - goto make_now; -#ifdef CONFIG_F2FS_FS_COMPRESSION - if (ino == F2FS_COMPRESS_INO(sbi)) + if (is_meta_ino(sbi, ino)) goto make_now; -#endif ret = do_read_inode(inode); if (ret) From 718693c84d8f4b235d030c377258f12f38a71c67 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 27 Sep 2022 10:44:47 +0800 Subject: [PATCH 324/401] f2fs: introduce cp_status sysfs entry This patch adds a new sysfs entry named cp_status, it can output checkpoint flags in real time. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/ABI/testing/sysfs-fs-f2fs | 24 ++++++++++++++++++++++++ fs/f2fs/sysfs.c | 8 ++++++++ 2 files changed, 32 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 083ac2d63eef..483639fb727b 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -466,6 +466,30 @@ Description: Show status of f2fs superblock in real time. 0x4000 SBI_IS_FREEZING freefs is in process ====== ===================== ================================= +What: /sys/fs/f2fs//stat/cp_status +Date: September 2022 +Contact: "Chao Yu" +Description: Show status of f2fs checkpoint in real time. + + =============================== ============================== + cp flag value + CP_UMOUNT_FLAG 0x00000001 + CP_ORPHAN_PRESENT_FLAG 0x00000002 + CP_COMPACT_SUM_FLAG 0x00000004 + CP_ERROR_FLAG 0x00000008 + CP_FSCK_FLAG 0x00000010 + CP_FASTBOOT_FLAG 0x00000020 + CP_CRC_RECOVERY_FLAG 0x00000040 + CP_NAT_BITS_FLAG 0x00000080 + CP_TRIMMED_FLAG 0x00000100 + CP_NOCRC_RECOVERY_FLAG 0x00000200 + CP_LARGE_NAT_BITMAP_FLAG 0x00000400 + CP_QUOTA_NEED_FSCK_FLAG 0x00000800 + CP_DISABLED_FLAG 0x00001000 + CP_DISABLED_QUICK_FLAG 0x00002000 + CP_RESIZEFS_FLAG 0x00004000 + =============================== ============================== + What: /sys/fs/f2fs//ckpt_thread_ioprio Date: January 2021 Contact: "Daeho Jeong" diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 39ebf0ad133a..df27afd71ef4 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -128,6 +128,12 @@ static ssize_t sb_status_show(struct f2fs_attr *a, return sprintf(buf, "%lx\n", sbi->s_flag); } +static ssize_t cp_status_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf) +{ + return sprintf(buf, "%x\n", le32_to_cpu(F2FS_CKPT(sbi)->ckpt_flags)); +} + static ssize_t pending_discard_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { @@ -1029,8 +1035,10 @@ static struct attribute *f2fs_feat_attrs[] = { ATTRIBUTE_GROUPS(f2fs_feat); F2FS_GENERAL_RO_ATTR(sb_status); +F2FS_GENERAL_RO_ATTR(cp_status); static struct attribute *f2fs_stat_attrs[] = { ATTR_LIST(sb_status), + ATTR_LIST(cp_status), NULL, }; ATTRIBUTE_GROUPS(f2fs_stat); From ca7efd71c3dffd5442b448dd553a903425222597 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Fri, 23 Sep 2022 15:17:55 +0800 Subject: [PATCH 325/401] f2fs: remove the unnecessary check in f2fs_xattr_fiemap Whehter or not error occurs, checking "err == 1" is unnecessary in f2fs_xattr_fiemap(), and just remove it here. Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a45b6ab2e2a5..a921cd40db78 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1816,7 +1816,7 @@ static int f2fs_xattr_fiemap(struct inode *inode, err = fiemap_fill_next_extent(fieinfo, 0, phys, len, flags); trace_f2fs_fiemap(inode, 0, phys, len, flags, err); - if (err || err == 1) + if (err) return err; } From a9cfee0ef98e99c8b1951dfd1d57a88580354d0d Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 28 Sep 2022 23:38:53 +0800 Subject: [PATCH 326/401] f2fs: support recording stop_checkpoint reason into super_block This patch supports to record stop_checkpoint error into f2fs_super_block.s_stop_reason[]. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 10 +++++++--- fs/f2fs/data.c | 6 ++++-- fs/f2fs/f2fs.h | 4 +++- fs/f2fs/file.c | 11 ++++++----- fs/f2fs/gc.c | 6 ++++-- fs/f2fs/inode.c | 3 ++- fs/f2fs/segment.c | 5 +++-- fs/f2fs/super.c | 20 ++++++++++++++++++++ include/linux/f2fs_fs.h | 17 ++++++++++++++++- 9 files changed, 65 insertions(+), 17 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 308b70812cbd..0c82dae082aa 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -26,12 +26,16 @@ static struct kmem_cache *ino_entry_slab; struct kmem_cache *f2fs_inode_entry_slab; -void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io) +void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io, + unsigned char reason) { f2fs_build_fault_attr(sbi, 0, 0); set_ckpt_flags(sbi, CP_ERROR_FLAG); - if (!end_io) + if (!end_io) { f2fs_flush_merged_writes(sbi); + + f2fs_handle_stop(sbi, reason); + } } /* @@ -122,7 +126,7 @@ retry: if (PTR_ERR(page) == -EIO && ++count <= DEFAULT_RETRY_IO_COUNT) goto retry; - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE); } return page; } diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a921cd40db78..3f2210e54577 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -333,7 +333,8 @@ static void f2fs_write_end_io(struct bio *bio) mempool_free(page, sbi->write_io_dummy); if (unlikely(bio->bi_status)) - f2fs_stop_checkpoint(sbi, true); + f2fs_stop_checkpoint(sbi, true, + STOP_CP_REASON_WRITE_FAIL); continue; } @@ -349,7 +350,8 @@ static void f2fs_write_end_io(struct bio *bio) if (unlikely(bio->bi_status)) { mapping_set_error(page->mapping, -EIO); if (type == F2FS_WB_CP_DATA) - f2fs_stop_checkpoint(sbi, true); + f2fs_stop_checkpoint(sbi, true, + STOP_CP_REASON_WRITE_FAIL); } f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) && diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index c494c40b644b..7d56948273be 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3556,6 +3556,7 @@ int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly); int f2fs_quota_sync(struct super_block *sb, int type); loff_t max_file_blocks(struct inode *inode); void f2fs_quota_off_umount(struct super_block *sb); +void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason); int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover); int f2fs_sync_fs(struct super_block *sb, int sync); int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi); @@ -3715,7 +3716,8 @@ static inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi) /* * checkpoint.c */ -void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io); +void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io, + unsigned char reason); void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi); struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index); struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4020f5e72a2c..c86e5e1601c9 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2145,7 +2145,8 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) if (ret) { if (ret == -EROFS) { ret = 0; - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, + STOP_CP_REASON_SHUTDOWN); set_sbi_flag(sbi, SBI_IS_SHUTDOWN); trace_f2fs_shutdown(sbi, in, ret); } @@ -2158,7 +2159,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) ret = freeze_bdev(sb->s_bdev); if (ret) goto out; - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN); set_sbi_flag(sbi, SBI_IS_SHUTDOWN); thaw_bdev(sb->s_bdev); break; @@ -2167,16 +2168,16 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) ret = f2fs_sync_fs(sb, 1); if (ret) goto out; - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN); set_sbi_flag(sbi, SBI_IS_SHUTDOWN); break; case F2FS_GOING_DOWN_NOSYNC: - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN); set_sbi_flag(sbi, SBI_IS_SHUTDOWN); break; case F2FS_GOING_DOWN_METAFLUSH: f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO); - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN); set_sbi_flag(sbi, SBI_IS_SHUTDOWN); break; case F2FS_GOING_DOWN_NEED_FSCK: diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 3a820e5cdaee..6e42dad0ac2d 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -74,7 +74,8 @@ static int gc_thread_func(void *data) if (time_to_inject(sbi, FAULT_CHECKPOINT)) { f2fs_show_injection_info(sbi, FAULT_CHECKPOINT); - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, + STOP_CP_REASON_FAULT_INJECT); } if (!sb_start_write_trylock(sbi->sb)) { @@ -1712,7 +1713,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SSA and SIT", segno, type, GET_SUM_TYPE((&sum->footer))); set_sbi_flag(sbi, SBI_NEED_FSCK); - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, + STOP_CP_REASON_CORRUPTED_SUMMARY); goto skip; } diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 93ec216da3e1..c972276027b4 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -713,7 +713,8 @@ retry: cond_resched(); goto retry; } else if (err != -ENOENT) { - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, + STOP_CP_REASON_UPDATE_INODE); } return; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 3f14c0a4fb89..54c86a551859 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -376,7 +376,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need) { if (time_to_inject(sbi, FAULT_CHECKPOINT)) { f2fs_show_injection_info(sbi, FAULT_CHECKPOINT); - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_FAULT_INJECT); } /* balance_fs_bg is able to be pending */ @@ -694,7 +694,8 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi) } while (ret && --count); if (ret) { - f2fs_stop_checkpoint(sbi, false); + f2fs_stop_checkpoint(sbi, false, + STOP_CP_REASON_FLUSH_FAIL); break; } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index b8e5fe244596..2533d309a924 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3846,6 +3846,26 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) return err; } +void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason) +{ + struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); + int err; + + f2fs_bug_on(sbi, reason >= MAX_STOP_REASON); + + f2fs_down_write(&sbi->sb_lock); + + if (raw_super->s_stop_reason[reason] < ((1 << BITS_PER_BYTE) - 1)) + raw_super->s_stop_reason[reason]++; + + err = f2fs_commit_super(sbi, false); + if (err) + f2fs_err(sbi, "f2fs_commit_super fails to record reason:%u err:%d", + reason, err); + + f2fs_up_write(&sbi->sb_lock); +} + static int f2fs_scan_devices(struct f2fs_sb_info *sbi) { struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index d445150c5350..5dd1e52b8997 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -73,6 +73,20 @@ struct f2fs_device { __le32 total_segments; } __packed; +/* reason of stop_checkpoint */ +enum stop_cp_reason { + STOP_CP_REASON_SHUTDOWN, + STOP_CP_REASON_FAULT_INJECT, + STOP_CP_REASON_META_PAGE, + STOP_CP_REASON_WRITE_FAIL, + STOP_CP_REASON_CORRUPTED_SUMMARY, + STOP_CP_REASON_UPDATE_INODE, + STOP_CP_REASON_FLUSH_FAIL, + STOP_CP_REASON_MAX, +}; + +#define MAX_STOP_REASON 32 + struct f2fs_super_block { __le32 magic; /* Magic Number */ __le16 major_ver; /* Major Version */ @@ -116,7 +130,8 @@ struct f2fs_super_block { __u8 hot_ext_count; /* # of hot file extension */ __le16 s_encoding; /* Filename charset encoding */ __le16 s_encoding_flags; /* Filename charset encoding flags */ - __u8 reserved[306]; /* valid reserved region */ + __u8 s_stop_reason[MAX_STOP_REASON]; /* stop checkpoint reason */ + __u8 reserved[274]; /* valid reserved region */ __le32 crc; /* checksum of superblock */ } __packed; From 95fa90c9e5a7f14c2497d5b032544478c9377c3a Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 28 Sep 2022 23:38:54 +0800 Subject: [PATCH 327/401] f2fs: support recording errors into superblock This patch supports to record detail reason of FSCORRUPTED error into f2fs_super_block.s_errors[]. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/compress.c | 2 ++ fs/f2fs/data.c | 24 +++++++++++++++++--- fs/f2fs/dir.c | 1 + fs/f2fs/f2fs.h | 5 +++++ fs/f2fs/file.c | 12 ++++++++-- fs/f2fs/gc.c | 2 ++ fs/f2fs/inline.c | 2 ++ fs/f2fs/inode.c | 6 ++++- fs/f2fs/node.c | 2 ++ fs/f2fs/recovery.c | 6 +++++ fs/f2fs/segment.c | 11 +++++++++ fs/f2fs/segment.h | 2 ++ fs/f2fs/super.c | 49 +++++++++++++++++++++++++++++++++++++++-- fs/f2fs/verity.c | 2 ++ fs/f2fs/xattr.c | 8 +++++++ include/linux/f2fs_fs.h | 25 ++++++++++++++++++++- 16 files changed, 150 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index c16bab5bd600..d315c2de136f 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -762,6 +762,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task) if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) { ret = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION); goto out_release; } @@ -950,6 +951,7 @@ static int __f2fs_cluster_blocks(struct inode *inode, if (f2fs_sanity_check_cluster(&dn)) { ret = -EFSCORRUPTED; + f2fs_handle_error(F2FS_I_SB(inode), ERROR_CORRUPTED_CLUSTER); goto fail; } diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 3f2210e54577..1c82a4a4e861 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -705,8 +705,10 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr, fio->is_por ? META_POR : (__is_meta_io(fio) ? - META_GENERIC : DATA_GENERIC_ENHANCE))) + META_GENERIC : DATA_GENERIC_ENHANCE))) { + f2fs_handle_error(fio->sbi, ERROR_INVALID_BLKADDR); return -EFSCORRUPTED; + } trace_f2fs_submit_page_bio(page, fio); @@ -906,8 +908,10 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio) fio->encrypted_page : fio->page; if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr, - __is_meta_io(fio) ? META_GENERIC : DATA_GENERIC)) + __is_meta_io(fio) ? META_GENERIC : DATA_GENERIC)) { + f2fs_handle_error(fio->sbi, ERROR_INVALID_BLKADDR); return -EFSCORRUPTED; + } trace_f2fs_submit_page_bio(page, fio); @@ -1217,6 +1221,8 @@ struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index, if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), dn.data_blkaddr, DATA_GENERIC_ENHANCE_READ)) { err = -EFSCORRUPTED; + f2fs_handle_error(F2FS_I_SB(inode), + ERROR_INVALID_BLKADDR); goto put_err; } goto got_it; @@ -1237,6 +1243,8 @@ struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index, dn.data_blkaddr, DATA_GENERIC_ENHANCE)) { err = -EFSCORRUPTED; + f2fs_handle_error(F2FS_I_SB(inode), + ERROR_INVALID_BLKADDR); goto put_err; } got_it: @@ -1550,6 +1558,7 @@ next_block: if (__is_valid_data_blkaddr(blkaddr) && !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE)) { err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); goto sync_out; } @@ -1595,6 +1604,8 @@ next_block: (flag != F2FS_GET_BLOCK_FIEMAP || IS_ENABLED(CONFIG_F2FS_CHECK_FS))) { err = -EFSCORRUPTED; + f2fs_handle_error(sbi, + ERROR_CORRUPTED_CLUSTER); goto sync_out; } if (flag == F2FS_GET_BLOCK_BMAP) { @@ -2076,6 +2087,8 @@ got_it: if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr, DATA_GENERIC_ENHANCE_READ)) { ret = -EFSCORRUPTED; + f2fs_handle_error(F2FS_I_SB(inode), + ERROR_INVALID_BLKADDR); goto out; } } else { @@ -2619,8 +2632,11 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) fio->old_blkaddr = ei.blk + page->index - ei.fofs; if (!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr, - DATA_GENERIC_ENHANCE)) + DATA_GENERIC_ENHANCE)) { + f2fs_handle_error(fio->sbi, + ERROR_INVALID_BLKADDR); return -EFSCORRUPTED; + } ipu_force = true; fio->need_lock = LOCK_DONE; @@ -2648,6 +2664,7 @@ got_it: !f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr, DATA_GENERIC_ENHANCE)) { err = -EFSCORRUPTED; + f2fs_handle_error(fio->sbi, ERROR_INVALID_BLKADDR); goto out_writepage; } @@ -3561,6 +3578,7 @@ repeat: if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) { err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); goto fail; } err = f2fs_submit_page_read(inode, page, blkaddr, 0, true); diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index d5bd7932fb64..21960a899b6a 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -1041,6 +1041,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, __func__, le16_to_cpu(de->name_len)); set_sbi_flag(sbi, SBI_NEED_FSCK); err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_CORRUPTED_DIRENT); goto out; } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 7d56948273be..b63b482c35a8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1815,6 +1815,10 @@ struct f2fs_sb_info { struct workqueue_struct *post_read_wq; /* post read workqueue */ + unsigned char errors[MAX_F2FS_ERRORS]; /* error flags */ + spinlock_t error_lock; /* protect errors array */ + bool error_dirty; /* errors of sb is dirty */ + struct kmem_cache *inline_xattr_slab; /* inline xattr entry */ unsigned int inline_xattr_slab_size; /* default inline xattr slab size */ @@ -3557,6 +3561,7 @@ int f2fs_quota_sync(struct super_block *sb, int type); loff_t max_file_blocks(struct inode *inode); void f2fs_quota_off_umount(struct super_block *sb); void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason); +void f2fs_handle_error(struct f2fs_sb_info *sbi, unsigned char error); int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover); int f2fs_sync_fs(struct super_block *sb, int sync); int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index c86e5e1601c9..7b3ed4a9bb46 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1156,6 +1156,7 @@ next_dnode: !f2fs_is_valid_blkaddr(sbi, *blkaddr, DATA_GENERIC_ENHANCE)) { f2fs_put_dnode(&dn); + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); return -EFSCORRUPTED; } @@ -1440,6 +1441,7 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start, if (!f2fs_is_valid_blkaddr(sbi, dn->data_blkaddr, DATA_GENERIC_ENHANCE)) { ret = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); break; } @@ -3323,8 +3325,10 @@ static int release_compress_blocks(struct dnode_of_data *dn, pgoff_t count) if (!__is_valid_data_blkaddr(blkaddr)) continue; if (unlikely(!f2fs_is_valid_blkaddr(sbi, blkaddr, - DATA_GENERIC_ENHANCE))) + DATA_GENERIC_ENHANCE))) { + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); return -EFSCORRUPTED; + } } while (count) { @@ -3485,8 +3489,10 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count) if (!__is_valid_data_blkaddr(blkaddr)) continue; if (unlikely(!f2fs_is_valid_blkaddr(sbi, blkaddr, - DATA_GENERIC_ENHANCE))) + DATA_GENERIC_ENHANCE))) { + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); return -EFSCORRUPTED; + } } while (count) { @@ -3758,6 +3764,8 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg) DATA_GENERIC_ENHANCE)) { ret = -EFSCORRUPTED; f2fs_put_dnode(&dn); + f2fs_handle_error(sbi, + ERROR_INVALID_BLKADDR); goto out; } diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 6e42dad0ac2d..d36bcb23ccfe 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1164,6 +1164,7 @@ static int ra_data_block(struct inode *inode, pgoff_t index) if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr, DATA_GENERIC_ENHANCE_READ))) { err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); goto put_page; } goto got_it; @@ -1182,6 +1183,7 @@ static int ra_data_block(struct inode *inode, pgoff_t index) if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr, DATA_GENERIC_ENHANCE))) { err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); goto put_page; } got_it: diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 73da93318036..21a495234ffd 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -160,6 +160,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) set_sbi_flag(fio.sbi, SBI_NEED_FSCK); f2fs_warn(fio.sbi, "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, run fsck to fix.", __func__, dn->inode->i_ino, dn->data_blkaddr); + f2fs_handle_error(fio.sbi, ERROR_INVALID_BLKADDR); return -EFSCORRUPTED; } @@ -412,6 +413,7 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, set_sbi_flag(F2FS_P_SB(page), SBI_NEED_FSCK); f2fs_warn(F2FS_P_SB(page), "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, run fsck to fix.", __func__, dir->i_ino, dn.data_blkaddr); + f2fs_handle_error(F2FS_P_SB(page), ERROR_INVALID_BLKADDR); err = -EFSCORRUPTED; goto out; } diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index c972276027b4..9f0d3864d9f1 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -81,8 +81,10 @@ static int __written_first_block(struct f2fs_sb_info *sbi, if (!__is_valid_data_blkaddr(addr)) return 1; - if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC_ENHANCE)) + if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC_ENHANCE)) { + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); return -EFSCORRUPTED; + } return 0; } @@ -415,6 +417,7 @@ static int do_read_inode(struct inode *inode) if (!sanity_check_inode(inode, node_page)) { f2fs_put_page(node_page, 1); + f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); return -EFSCORRUPTED; } @@ -510,6 +513,7 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) ret = -EFSCORRUPTED; trace_f2fs_iget_exit(inode, ret); iput(inode); + f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); return ERR_PTR(ret); } diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 9263bf5f10d3..983572f23896 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -36,6 +36,7 @@ int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid) set_sbi_flag(sbi, SBI_NEED_FSCK); f2fs_warn(sbi, "%s: out-of-range nid=%x, run fsck to fix.", __func__, nid); + f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); return -EFSCORRUPTED; } return 0; @@ -1295,6 +1296,7 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs) if (unlikely(new_ni.blk_addr != NULL_ADDR)) { err = -EFSCORRUPTED; set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); goto fail; } #endif diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 5c9facec98f6..dea95b48b647 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -507,6 +507,7 @@ got_it: if (ofs_in_node >= max_addrs) { f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%lu, nid:%u, max:%u", ofs_in_node, dn->inode->i_ino, nid, max_addrs); + f2fs_handle_error(sbi, ERROR_INCONSISTENT_SUMMARY); return -EFSCORRUPTED; } @@ -637,6 +638,7 @@ retry_dn: inode->i_ino, ofs_of_node(dn.node_page), ofs_of_node(page)); err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER); goto err; } @@ -649,12 +651,14 @@ retry_dn: if (__is_valid_data_blkaddr(src) && !f2fs_is_valid_blkaddr(sbi, src, META_POR)) { err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); goto err; } if (__is_valid_data_blkaddr(dest) && !f2fs_is_valid_blkaddr(sbi, dest, META_POR)) { err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); goto err; } @@ -712,6 +716,8 @@ retry_prev: f2fs_err(sbi, "Inconsistent dest blkaddr:%u, ino:%lu, ofs:%u", dest, inode->i_ino, dn.ofs_in_node); err = -EFSCORRUPTED; + f2fs_handle_error(sbi, + ERROR_INVALID_BLKADDR); goto err; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 54c86a551859..d7b13127b0b8 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -312,6 +312,8 @@ static int __f2fs_commit_atomic_write(struct inode *inode) DATA_GENERIC_ENHANCE)) { f2fs_put_dnode(&dn); ret = -EFSCORRUPTED; + f2fs_handle_error(sbi, + ERROR_INVALID_BLKADDR); goto out; } @@ -3433,6 +3435,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio) f2fs_warn(sbi, "%s: incorrect segment(%u) type, run fsck to fix.", __func__, segno); err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INCONSISTENT_SUM_TYPE); goto drop_bio; } @@ -4381,6 +4384,8 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) if (se->type >= NR_PERSISTENT_LOG) { f2fs_err(sbi, "Invalid segment type: %u, segno: %u", se->type, start); + f2fs_handle_error(sbi, + ERROR_INCONSISTENT_SUM_TYPE); return -EFSCORRUPTED; } @@ -4417,6 +4422,7 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) f2fs_err(sbi, "Wrong journal entry on segno %u", start); err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_CORRUPTED_JOURNAL); break; } @@ -4436,6 +4442,7 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) f2fs_err(sbi, "Invalid segment type: %u, segno: %u", se->type, start); err = -EFSCORRUPTED; + f2fs_handle_error(sbi, ERROR_INCONSISTENT_SUM_TYPE); break; } @@ -4467,6 +4474,7 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) if (sit_valid_blocks[NODE] != valid_node_count(sbi)) { f2fs_err(sbi, "SIT is corrupted node# %u vs %u", sit_valid_blocks[NODE], valid_node_count(sbi)); + f2fs_handle_error(sbi, ERROR_INCONSISTENT_NODE_COUNT); return -EFSCORRUPTED; } @@ -4475,6 +4483,7 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) f2fs_err(sbi, "SIT is corrupted data# %u %u vs %u", sit_valid_blocks[DATA], sit_valid_blocks[NODE], valid_user_blocks(sbi)); + f2fs_handle_error(sbi, ERROR_INCONSISTENT_BLOCK_COUNT); return -EFSCORRUPTED; } @@ -4625,6 +4634,7 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi) f2fs_err(sbi, "Current segment has invalid alloc_type:%d", curseg->alloc_type); + f2fs_handle_error(sbi, ERROR_INVALID_CURSEG); return -EFSCORRUPTED; } @@ -4642,6 +4652,7 @@ out: "Current segment's next free block offset is inconsistent with bitmap, logtype:%u, segno:%u, type:%u, next_blkoff:%u, blkofs:%u", i, curseg->segno, curseg->alloc_type, curseg->next_blkoff, blkofs); + f2fs_handle_error(sbi, ERROR_INVALID_CURSEG); return -EFSCORRUPTED; } } diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index d1d63766f2c7..be8f2d7d007b 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -753,6 +753,7 @@ static inline int check_block_count(struct f2fs_sb_info *sbi, f2fs_err(sbi, "Mismatch valid blocks %d vs. %d", GET_SIT_VBLOCKS(raw_sit), valid_blocks); set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_handle_error(sbi, ERROR_INCONSISTENT_SIT); return -EFSCORRUPTED; } @@ -767,6 +768,7 @@ static inline int check_block_count(struct f2fs_sb_info *sbi, f2fs_err(sbi, "Wrong valid blocks %d or segno %u", GET_SIT_VBLOCKS(raw_sit), segno); set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_handle_error(sbi, ERROR_INCONSISTENT_SIT); return -EFSCORRUPTED; } return 0; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2533d309a924..6cf72fbf2054 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3851,8 +3851,6 @@ void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason) struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); int err; - f2fs_bug_on(sbi, reason >= MAX_STOP_REASON); - f2fs_down_write(&sbi->sb_lock); if (raw_super->s_stop_reason[reason] < ((1 << BITS_PER_BYTE) - 1)) @@ -3862,7 +3860,51 @@ void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason) if (err) f2fs_err(sbi, "f2fs_commit_super fails to record reason:%u err:%d", reason, err); + f2fs_up_write(&sbi->sb_lock); +} +static void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag) +{ + spin_lock(&sbi->error_lock); + if (!test_bit(flag, (unsigned long *)sbi->errors)) { + set_bit(flag, (unsigned long *)sbi->errors); + sbi->error_dirty = true; + } + spin_unlock(&sbi->error_lock); +} + +static bool f2fs_update_errors(struct f2fs_sb_info *sbi) +{ + bool need_update = false; + + spin_lock(&sbi->error_lock); + if (sbi->error_dirty) { + memcpy(F2FS_RAW_SUPER(sbi)->s_errors, sbi->errors, + MAX_F2FS_ERRORS); + sbi->error_dirty = false; + need_update = true; + } + spin_unlock(&sbi->error_lock); + + return need_update; +} + +void f2fs_handle_error(struct f2fs_sb_info *sbi, unsigned char error) +{ + int err; + + f2fs_save_errors(sbi, error); + + f2fs_down_write(&sbi->sb_lock); + + if (!f2fs_update_errors(sbi)) + goto out_unlock; + + err = f2fs_commit_super(sbi, false); + if (err) + f2fs_err(sbi, "f2fs_commit_super fails to record errors:%u, err:%d", + error, err); +out_unlock: f2fs_up_write(&sbi->sb_lock); } @@ -4213,6 +4255,9 @@ try_onemore: goto free_devices; } + spin_lock_init(&sbi->error_lock); + memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS); + sbi->total_valid_node_count = le32_to_cpu(sbi->ckpt->valid_node_count); percpu_counter_set(&sbi->total_valid_inode_count, diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c index 97ec60f39d69..f0805e51b3fe 100644 --- a/fs/f2fs/verity.c +++ b/fs/f2fs/verity.c @@ -240,6 +240,8 @@ static int f2fs_get_verity_descriptor(struct inode *inode, void *buf, if (pos + size < pos || pos + size > inode->i_sb->s_maxbytes || pos < f2fs_verity_metadata_pos(inode) || size > INT_MAX) { f2fs_warn(F2FS_I_SB(inode), "invalid verity xattr"); + f2fs_handle_error(F2FS_I_SB(inode), + ERROR_CORRUPTED_VERITY_XATTR); return -EFSCORRUPTED; } if (buf_size) { diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index c76c15086e5f..dc2e8637189e 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -367,6 +367,8 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage, inode->i_ino); set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); err = -EFSCORRUPTED; + f2fs_handle_error(F2FS_I_SB(inode), + ERROR_CORRUPTED_XATTR); goto out; } check: @@ -583,6 +585,8 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) inode->i_ino); set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); error = -EFSCORRUPTED; + f2fs_handle_error(F2FS_I_SB(inode), + ERROR_CORRUPTED_XATTR); goto cleanup; } @@ -658,6 +662,8 @@ static int __f2fs_setxattr(struct inode *inode, int index, inode->i_ino); set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); error = -EFSCORRUPTED; + f2fs_handle_error(F2FS_I_SB(inode), + ERROR_CORRUPTED_XATTR); goto exit; } @@ -684,6 +690,8 @@ static int __f2fs_setxattr(struct inode *inode, int index, inode->i_ino, ENTRY_SIZE(last)); set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); error = -EFSCORRUPTED; + f2fs_handle_error(F2FS_I_SB(inode), + ERROR_CORRUPTED_XATTR); goto exit; } last = XATTR_NEXT_ENTRY(last); diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 5dd1e52b8997..ee0d75d9a302 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -87,6 +87,28 @@ enum stop_cp_reason { #define MAX_STOP_REASON 32 +/* detail reason for EFSCORRUPTED */ +enum f2fs_error { + ERROR_CORRUPTED_CLUSTER, + ERROR_FAIL_DECOMPRESSION, + ERROR_INVALID_BLKADDR, + ERROR_CORRUPTED_DIRENT, + ERROR_CORRUPTED_INODE, + ERROR_INCONSISTENT_SUMMARY, + ERROR_INCONSISTENT_FOOTER, + ERROR_INCONSISTENT_SUM_TYPE, + ERROR_CORRUPTED_JOURNAL, + ERROR_INCONSISTENT_NODE_COUNT, + ERROR_INCONSISTENT_BLOCK_COUNT, + ERROR_INVALID_CURSEG, + ERROR_INCONSISTENT_SIT, + ERROR_CORRUPTED_VERITY_XATTR, + ERROR_CORRUPTED_XATTR, + ERROR_MAX, +}; + +#define MAX_F2FS_ERRORS 16 + struct f2fs_super_block { __le32 magic; /* Magic Number */ __le16 major_ver; /* Major Version */ @@ -131,7 +153,8 @@ struct f2fs_super_block { __le16 s_encoding; /* Filename charset encoding */ __le16 s_encoding_flags; /* Filename charset encoding flags */ __u8 s_stop_reason[MAX_STOP_REASON]; /* stop checkpoint reason */ - __u8 reserved[274]; /* valid reserved region */ + __u8 s_errors[MAX_F2FS_ERRORS]; /* reason of image corrupts */ + __u8 reserved[258]; /* valid reserved region */ __le32 crc; /* checksum of superblock */ } __packed; From 52f1c45dde9136f964d63a77d19826c8a74e2c7f Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Wed, 17 Aug 2022 14:58:44 +0900 Subject: [PATCH 328/401] 9p: trans_fd/p9_conn_cancel: drop client lock earlier syzbot reported a double-lock here and we no longer need this lock after requests have been moved off to local list: just drop the lock earlier. Link: https://lkml.kernel.org/r/20220904064028.1305220-1-asmadeus@codewreck.org Reported-by: syzbot+50f7e8d06c3768dd97f3@syzkaller.appspotmail.com Signed-off-by: Dominique Martinet Tested-by: Schspa Shi --- net/9p/trans_fd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index e758978b44be..60fcc6b30b46 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -205,6 +205,8 @@ static void p9_conn_cancel(struct p9_conn *m, int err) list_move(&req->req_list, &cancel_list); } + spin_unlock(&m->client->lock); + list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); list_del(&req->req_list); @@ -212,7 +214,6 @@ static void p9_conn_cancel(struct p9_conn *m, int err) req->t_err = err; p9_client_cb(m->client, req, REQ_STATUS_ERROR); } - spin_unlock(&m->client->lock); } static __poll_t From e7c6219778e46143ee9e68a25febac10a66383ae Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Fri, 15 Jul 2022 23:32:28 +0200 Subject: [PATCH 329/401] net/9p: split message size argument into 't_size' and 'r_size' pair Refactor 'max_size' argument of p9_tag_alloc() and 'req_size' argument of p9_client_prepare_req() both into a pair of arguments 't_size' and 'r_size' respectively to allow handling the buffer size for request and reply separately from each other. Link: https://lkml.kernel.org/r/9431a25fe4b37fd12cecbd715c13af71f701f220.1657920926.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck Signed-off-by: Dominique Martinet --- net/9p/client.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/net/9p/client.c b/net/9p/client.c index 0a6110e15d0f..0bd7e43e5c4f 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -255,24 +255,26 @@ static struct kmem_cache *p9_req_cache; * p9_tag_alloc - Allocate a new request. * @c: Client session. * @type: Transaction type. - * @max_size: Maximum packet size for this request. + * @t_size: Buffer size for holding this request. + * @r_size: Buffer size for holding server's reply on this request. * * Context: Process context. * Return: Pointer to new request. */ static struct p9_req_t * -p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size) +p9_tag_alloc(struct p9_client *c, int8_t type, uint t_size, uint r_size) { struct p9_req_t *req = kmem_cache_alloc(p9_req_cache, GFP_NOFS); - int alloc_msize = min(c->msize, max_size); + int alloc_tsize = min(c->msize, t_size); + int alloc_rsize = min(c->msize, r_size); int tag; if (!req) return ERR_PTR(-ENOMEM); - if (p9_fcall_init(c, &req->tc, alloc_msize)) + if (p9_fcall_init(c, &req->tc, alloc_tsize)) goto free_req; - if (p9_fcall_init(c, &req->rc, alloc_msize)) + if (p9_fcall_init(c, &req->rc, alloc_rsize)) goto free; p9pdu_reset(&req->tc); @@ -592,7 +594,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) } static struct p9_req_t *p9_client_prepare_req(struct p9_client *c, - int8_t type, int req_size, + int8_t type, uint t_size, uint r_size, const char *fmt, va_list ap) { int err; @@ -608,7 +610,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c, if (c->status == BeginDisconnect && type != P9_TCLUNK) return ERR_PTR(-EIO); - req = p9_tag_alloc(c, type, req_size); + req = p9_tag_alloc(c, type, t_size, r_size); if (IS_ERR(req)) return req; @@ -645,7 +647,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) struct p9_req_t *req; va_start(ap, fmt); - req = p9_client_prepare_req(c, type, c->msize, fmt, ap); + req = p9_client_prepare_req(c, type, c->msize, c->msize, fmt, ap); va_end(ap); if (IS_ERR(req)) return req; @@ -743,7 +745,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, /* We allocate a inline protocol data of only 4k bytes. * The actual content is passed in zero-copy fashion. */ - req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, fmt, ap); + req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, P9_ZC_HDR_SZ, fmt, ap); va_end(ap); if (IS_ERR(req)) return req; From 58d331312bf78a10740fc3c6c370c98e8c53fa6b Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Fri, 15 Jul 2022 23:32:30 +0200 Subject: [PATCH 330/401] 9p: add P9_ERRMAX for 9p2000 and 9p2000.u Add P9_ERRMAX macro to 9P protocol header which reflects the maximum error string length of Rerror replies for 9p2000 and 9p2000.u protocol versions. Unfortunately a maximum error string length is not defined by the 9p2000 spec, picking 128 as value for now, as this seems to be a common max. size for POSIX error strings in practice. 9p2000.L protocol version uses Rlerror replies instead which does not contain an error string. Link: https://lkml.kernel.org/r/3f23191d21032e7c14852b1e1a4ae26417a36739.1657920926.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck Signed-off-by: Dominique Martinet --- include/net/9p/9p.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 24a509f559ee..13abe013af21 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -331,6 +331,9 @@ enum p9_qid_t { /* size of header for zero copy read/write */ #define P9_ZC_HDR_SZ 4096 +/* maximum length of an error string */ +#define P9_ERRMAX 128 + /** * struct p9_qid - file system entity information * @type: 8-bit type &p9_qid_t From 1effdbf94a728b74b23a24ce7b6f1d1d9a2480a4 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Fri, 15 Jul 2022 23:32:34 +0200 Subject: [PATCH 331/401] net/9p: add p9_msg_buf_size() This new function calculates a buffer size suitable for holding the intended 9p request or response. For rather small message types (which applies to almost all 9p message types actually) simply use hard coded values. For some variable-length and potentially large message types calculate a more precise value according to what data is actually transmitted to avoid unnecessarily huge buffers. So p9_msg_buf_size() divides the individual 9p message types into 3 message size categories: - dynamically calculated message size (i.e. potentially large) - 8k hard coded message size - 4k hard coded message size As for the latter two hard coded message types: for most 9p message types it is pretty obvious whether they would always fit into 4k or 8k. But for some of them it depends on the maximum directory entry name length allowed by OS and filesystem for determining into which of the two size categories they would fit into. Currently Linux supports directory entry names up to NAME_MAX (255), however when comparing the limitation of individual filesystems, ReiserFS theoretically supports up to slightly below 4k long names. So in order to make this code more future proof, and as revisiting it later on is a bit tedious and has the potential to miss out details, the decision [1] was made to take 4k as basis as for max. name length. Link: https://lkml.kernel.org/r/bd6be891cf67e867688e8c8796d06408bfafa0d9.1657920926.git.linux_oss@crudebyte.com Link: https://lore.kernel.org/all/5564296.oo812IJUPE@silver/ [1] Signed-off-by: Christian Schoenebeck Signed-off-by: Dominique Martinet --- net/9p/protocol.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++ net/9p/protocol.h | 2 + 2 files changed, 169 insertions(+) diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 83694c631989..4e3a2a1ffcb3 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -23,6 +23,173 @@ #include +/* len[2] text[len] */ +#define P9_STRLEN(s) \ + (2 + min_t(size_t, s ? strlen(s) : 0, USHRT_MAX)) + +/** + * p9_msg_buf_size - Returns a buffer size sufficiently large to hold the + * intended 9p message. + * @c: client + * @type: message type + * @fmt: format template for assembling request message + * (see p9pdu_vwritef) + * @ap: variable arguments to be fed to passed format template + * (see p9pdu_vwritef) + * + * Note: Even for response types (P9_R*) the format template and variable + * arguments must always be for the originating request type (P9_T*). + */ +size_t p9_msg_buf_size(struct p9_client *c, enum p9_msg_t type, + const char *fmt, va_list ap) +{ + /* size[4] type[1] tag[2] */ + const int hdr = 4 + 1 + 2; + /* ename[s] errno[4] */ + const int rerror_size = hdr + P9_ERRMAX + 4; + /* ecode[4] */ + const int rlerror_size = hdr + 4; + const int err_size = + c->proto_version == p9_proto_2000L ? rlerror_size : rerror_size; + + static_assert(NAME_MAX <= 4*1024, "p9_msg_buf_size() currently assumes " + "a max. allowed directory entry name length of 4k"); + + switch (type) { + + /* message types not used at all */ + case P9_TERROR: + case P9_TLERROR: + case P9_TAUTH: + case P9_RAUTH: + BUG(); + + /* variable length & potentially large message types */ + case P9_TATTACH: + BUG_ON(strcmp("ddss?u", fmt)); + va_arg(ap, int32_t); + va_arg(ap, int32_t); + { + const char *uname = va_arg(ap, const char *); + const char *aname = va_arg(ap, const char *); + /* fid[4] afid[4] uname[s] aname[s] n_uname[4] */ + return hdr + 4 + 4 + P9_STRLEN(uname) + P9_STRLEN(aname) + 4; + } + case P9_TWALK: + BUG_ON(strcmp("ddT", fmt)); + va_arg(ap, int32_t); + va_arg(ap, int32_t); + { + uint i, nwname = va_arg(ap, int); + size_t wname_all; + const char **wnames = va_arg(ap, const char **); + for (i = 0, wname_all = 0; i < nwname; ++i) { + wname_all += P9_STRLEN(wnames[i]); + } + /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */ + return hdr + 4 + 4 + 2 + wname_all; + } + case P9_RWALK: + BUG_ON(strcmp("ddT", fmt)); + va_arg(ap, int32_t); + va_arg(ap, int32_t); + { + uint nwname = va_arg(ap, int); + /* nwqid[2] nwqid*(wqid[13]) */ + return max_t(size_t, hdr + 2 + nwname * 13, err_size); + } + case P9_TCREATE: + BUG_ON(strcmp("dsdb?s", fmt)); + va_arg(ap, int32_t); + { + const char *name = va_arg(ap, const char *); + if (c->proto_version == p9_proto_legacy) { + /* fid[4] name[s] perm[4] mode[1] */ + return hdr + 4 + P9_STRLEN(name) + 4 + 1; + } else { + va_arg(ap, int32_t); + va_arg(ap, int); + { + const char *ext = va_arg(ap, const char *); + /* fid[4] name[s] perm[4] mode[1] extension[s] */ + return hdr + 4 + P9_STRLEN(name) + 4 + 1 + P9_STRLEN(ext); + } + } + } + case P9_TLCREATE: + BUG_ON(strcmp("dsddg", fmt)); + va_arg(ap, int32_t); + { + const char *name = va_arg(ap, const char *); + /* fid[4] name[s] flags[4] mode[4] gid[4] */ + return hdr + 4 + P9_STRLEN(name) + 4 + 4 + 4; + } + case P9_RREAD: + case P9_RREADDIR: + BUG_ON(strcmp("dqd", fmt)); + va_arg(ap, int32_t); + va_arg(ap, int64_t); + { + const int32_t count = va_arg(ap, int32_t); + /* count[4] data[count] */ + return max_t(size_t, hdr + 4 + count, err_size); + } + case P9_TWRITE: + BUG_ON(strcmp("dqV", fmt)); + va_arg(ap, int32_t); + va_arg(ap, int64_t); + { + const int32_t count = va_arg(ap, int32_t); + /* fid[4] offset[8] count[4] data[count] */ + return hdr + 4 + 8 + 4 + count; + } + case P9_TRENAMEAT: + BUG_ON(strcmp("dsds", fmt)); + va_arg(ap, int32_t); + { + const char *oldname, *newname; + oldname = va_arg(ap, const char *); + va_arg(ap, int32_t); + newname = va_arg(ap, const char *); + /* olddirfid[4] oldname[s] newdirfid[4] newname[s] */ + return hdr + 4 + P9_STRLEN(oldname) + 4 + P9_STRLEN(newname); + } + case P9_TSYMLINK: + BUG_ON(strcmp("dssg", fmt)); + va_arg(ap, int32_t); + { + const char *name = va_arg(ap, const char *); + const char *symtgt = va_arg(ap, const char *); + /* fid[4] name[s] symtgt[s] gid[4] */ + return hdr + 4 + P9_STRLEN(name) + P9_STRLEN(symtgt) + 4; + } + + case P9_RERROR: + return rerror_size; + case P9_RLERROR: + return rlerror_size; + + /* small message types */ + case P9_TWSTAT: + case P9_RSTAT: + case P9_RREADLINK: + case P9_TXATTRWALK: + case P9_TXATTRCREATE: + case P9_TLINK: + case P9_TMKDIR: + case P9_TMKNOD: + case P9_TRENAME: + case P9_TUNLINKAT: + case P9_TLOCK: + return 8 * 1024; + + /* tiny message types */ + default: + return 4 * 1024; + + } +} + static int p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...); diff --git a/net/9p/protocol.h b/net/9p/protocol.h index 6d719c30331a..ad2283d1f96b 100644 --- a/net/9p/protocol.h +++ b/net/9p/protocol.h @@ -8,6 +8,8 @@ * Copyright (C) 2008 by IBM, Corp. */ +size_t p9_msg_buf_size(struct p9_client *c, enum p9_msg_t type, + const char *fmt, va_list ap); int p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, va_list ap); int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...); From 01d205d936ae18532e14814808592b926aacc6d5 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Fri, 15 Jul 2022 23:33:09 +0200 Subject: [PATCH 332/401] net/9p: add 'pooled_rbuffers' flag to struct p9_trans_module This is a preparatory change for the subsequent patch: the RDMA transport pulls the buffers for its 9p response messages from a shared pool. [1] So this case has to be considered when choosing an appropriate response message size in the subsequent patch. Link: https://lore.kernel.org/all/Ys3jjg52EIyITPua@codewreck.org/ [1] Link: https://lkml.kernel.org/r/79d24310226bc4eb037892b5c097ec4ad4819a03.1657920926.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck Signed-off-by: Dominique Martinet --- include/net/9p/transport.h | 5 +++++ net/9p/trans_fd.c | 1 + net/9p/trans_rdma.c | 1 + net/9p/trans_virtio.c | 1 + net/9p/trans_xen.c | 1 + 5 files changed, 9 insertions(+) diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index ff842f963071..766ec07c9599 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h @@ -19,6 +19,10 @@ * @list: used to maintain a list of currently available transports * @name: the human-readable name of the transport * @maxsize: transport provided maximum packet size + * @pooled_rbuffers: currently only set for RDMA transport which pulls the + * response buffers from a shared pool, and accordingly + * we're less flexible when choosing the response message + * size in this case * @def: set if this transport should be considered the default * @create: member function to create a new connection on this transport * @close: member function to discard a connection on this transport @@ -38,6 +42,7 @@ struct p9_trans_module { struct list_head list; char *name; /* name of transport */ int maxsize; /* max message size of transport */ + bool pooled_rbuffers; int def; /* this transport should be default */ struct module *owner; int (*create)(struct p9_client *client, diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 60fcc6b30b46..25d422c473e8 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -1083,6 +1083,7 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args) static struct p9_trans_module p9_tcp_trans = { .name = "tcp", .maxsize = MAX_SOCK_BUF, + .pooled_rbuffers = false, .def = 0, .create = p9_fd_create_tcp, .close = p9_fd_close, diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index d817d3745238..6ff706760676 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c @@ -739,6 +739,7 @@ error: static struct p9_trans_module p9_rdma_trans = { .name = "rdma", .maxsize = P9_RDMA_MAXSIZE, + .pooled_rbuffers = true, .def = 0, .owner = THIS_MODULE, .create = rdma_create_trans, diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index b84d35cf6899..e757f0601304 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -802,6 +802,7 @@ static struct p9_trans_module p9_virtio_trans = { * page in zero copy. */ .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3), + .pooled_rbuffers = false, .def = 1, .owner = THIS_MODULE, }; diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index 227f89cc7237..41c57d40efb6 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -246,6 +246,7 @@ static irqreturn_t xen_9pfs_front_event_handler(int irq, void *r) static struct p9_trans_module p9_xen_trans = { .name = "xen", .maxsize = 1 << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT - 2), + .pooled_rbuffers = false, .def = 1, .create = p9_xen_create, .close = p9_xen_close, From 60ece0833b6c2bc1465eb2803fec20b670e2ee93 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Fri, 15 Jul 2022 23:33:56 +0200 Subject: [PATCH 333/401] net/9p: allocate appropriate reduced message buffers So far 'msize' was simply used for all 9p message types, which is far too much and slowed down performance tremendously with large values for user configurable 'msize' option. Let's stop this waste by using the new p9_msg_buf_size() function for allocating more appropriate, smaller buffers according to what is actually sent over the wire. Only exception: RDMA transport is currently excluded from this message size optimization - for its response buffers that is - as RDMA transport would not cope with it, due to its response buffers being pulled from a shared pool. [1] Link: https://lore.kernel.org/all/Ys3jjg52EIyITPua@codewreck.org/ [1] Link: https://lkml.kernel.org/r/3f51590535dc96ed0a165b8218c57639cfa5c36c.1657920926.git.linux_oss@crudebyte.com Signed-off-by: Christian Schoenebeck Signed-off-by: Dominique Martinet --- net/9p/client.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/net/9p/client.c b/net/9p/client.c index 0bd7e43e5c4f..aaa37b07e30a 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -255,19 +255,35 @@ static struct kmem_cache *p9_req_cache; * p9_tag_alloc - Allocate a new request. * @c: Client session. * @type: Transaction type. - * @t_size: Buffer size for holding this request. - * @r_size: Buffer size for holding server's reply on this request. + * @t_size: Buffer size for holding this request + * (automatic calculation by format template if 0). + * @r_size: Buffer size for holding server's reply on this request + * (automatic calculation by format template if 0). + * @fmt: Format template for assembling 9p request message + * (see p9pdu_vwritef). + * @ap: Variable arguments to be fed to passed format template + * (see p9pdu_vwritef). * * Context: Process context. * Return: Pointer to new request. */ static struct p9_req_t * -p9_tag_alloc(struct p9_client *c, int8_t type, uint t_size, uint r_size) +p9_tag_alloc(struct p9_client *c, int8_t type, uint t_size, uint r_size, + const char *fmt, va_list ap) { struct p9_req_t *req = kmem_cache_alloc(p9_req_cache, GFP_NOFS); - int alloc_tsize = min(c->msize, t_size); - int alloc_rsize = min(c->msize, r_size); + int alloc_tsize; + int alloc_rsize; int tag; + va_list apc; + + va_copy(apc, ap); + alloc_tsize = min_t(size_t, c->msize, + t_size ?: p9_msg_buf_size(c, type, fmt, apc)); + va_end(apc); + + alloc_rsize = min_t(size_t, c->msize, + r_size ?: p9_msg_buf_size(c, type + 1, fmt, ap)); if (!req) return ERR_PTR(-ENOMEM); @@ -599,6 +615,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c, { int err; struct p9_req_t *req; + va_list apc; p9_debug(P9_DEBUG_MUX, "client %p op %d\n", c, type); @@ -610,7 +627,9 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c, if (c->status == BeginDisconnect && type != P9_TCLUNK) return ERR_PTR(-EIO); - req = p9_tag_alloc(c, type, t_size, r_size); + va_copy(apc, ap); + req = p9_tag_alloc(c, type, t_size, r_size, fmt, apc); + va_end(apc); if (IS_ERR(req)) return req; @@ -645,9 +664,18 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) int sigpending, err; unsigned long flags; struct p9_req_t *req; + /* Passing zero for tsize/rsize to p9_client_prepare_req() tells it to + * auto determine an appropriate (small) request/response size + * according to actual message data being sent. Currently RDMA + * transport is excluded from this response message size optimization, + * as it would not cope with it, due to its pooled response buffers + * (using an optimized request size for RDMA as well though). + */ + const uint tsize = 0; + const uint rsize = c->trans_mod->pooled_rbuffers ? c->msize : 0; va_start(ap, fmt); - req = p9_client_prepare_req(c, type, c->msize, c->msize, fmt, ap); + req = p9_client_prepare_req(c, type, tsize, rsize, fmt, ap); va_end(ap); if (IS_ERR(req)) return req; From 5e85eba6f50dc288c22083a7e213152bcc4b8208 Mon Sep 17 00:00:00 2001 From: Vidya Sagar Date: Tue, 13 Sep 2022 18:48:21 +0530 Subject: [PATCH 334/401] PCI/ASPM: Refactor L1 PM Substates Control Register programming Refactor the code to extract the common code to program Control Registers 1 and 2 of the L1 PM Substates capability to a new function aspm_program_l1ss() and call it for both parent and child devices. [bhelgaas: squash in update to preserve fields we're not updating from https://lore.kernel.org/r/36fa13c5-e0f8-022f-77f7-7908e4df98b8@nvidia.com] Link: https://lore.kernel.org/r/20220913131822.16557-2-vidyas@nvidia.com Signed-off-by: Vidya Sagar Signed-off-by: Bjorn Helgaas --- drivers/pci/pcie/aspm.c | 72 ++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index a8aec190986c..b4bdadc4ac35 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -455,6 +455,31 @@ static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos, pci_write_config_dword(pdev, pos, val); } +static void aspm_program_l1ss(struct pci_dev *dev, u32 ctl1, u32 ctl2) +{ + u16 l1ss = dev->l1ss; + u32 l1_2_enable; + + /* + * Per PCIe r6.0, sec 5.5.4, T_POWER_ON in PCI_L1SS_CTL2 must be + * programmed prior to setting the L1.2 enable bits in PCI_L1SS_CTL1. + */ + pci_write_config_dword(dev, l1ss + PCI_L1SS_CTL2, ctl2); + + /* + * In addition, Common_Mode_Restore_Time and LTR_L1.2_THRESHOLD in + * PCI_L1SS_CTL1 must be programmed *before* setting the L1.2 + * enable bits, even though they're all in PCI_L1SS_CTL1. + */ + l1_2_enable = ctl1 & PCI_L1SS_CTL1_L1_2_MASK; + ctl1 &= ~PCI_L1SS_CTL1_L1_2_MASK; + + pci_write_config_dword(dev, l1ss + PCI_L1SS_CTL1, ctl1); + if (l1_2_enable) + pci_write_config_dword(dev, l1ss + PCI_L1SS_CTL1, + ctl1 | l1_2_enable); +} + /* Calculate L1.2 PM substate timing parameters */ static void aspm_calc_l1ss_info(struct pcie_link_state *link, u32 parent_l1ss_cap, u32 child_l1ss_cap) @@ -464,7 +489,6 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link, u32 t_common_mode, t_power_on, l1_2_threshold, scale, value; u32 ctl1 = 0, ctl2 = 0; u32 pctl1, pctl2, cctl1, cctl2; - u32 pl1_2_enables, cl1_2_enables; if (!(link->aspm_support & ASPM_STATE_L1_2_MASK)) return; @@ -513,39 +537,21 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link, ctl2 == pctl2 && ctl2 == cctl2) return; - /* Disable L1.2 while updating. See PCIe r5.0, sec 5.5.4, 7.8.3.3 */ - pl1_2_enables = pctl1 & PCI_L1SS_CTL1_L1_2_MASK; - cl1_2_enables = cctl1 & PCI_L1SS_CTL1_L1_2_MASK; + pctl1 &= ~(PCI_L1SS_CTL1_CM_RESTORE_TIME | + PCI_L1SS_CTL1_LTR_L12_TH_VALUE | + PCI_L1SS_CTL1_LTR_L12_TH_SCALE); + pctl1 |= (ctl1 & (PCI_L1SS_CTL1_CM_RESTORE_TIME | + PCI_L1SS_CTL1_LTR_L12_TH_VALUE | + PCI_L1SS_CTL1_LTR_L12_TH_SCALE)); + aspm_program_l1ss(parent, pctl1, ctl2); - if (pl1_2_enables || cl1_2_enables) { - pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_L1_2_MASK, 0); - pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_L1_2_MASK, 0); - } - - /* Program T_POWER_ON times in both ports */ - pci_write_config_dword(parent, parent->l1ss + PCI_L1SS_CTL2, ctl2); - pci_write_config_dword(child, child->l1ss + PCI_L1SS_CTL2, ctl2); - - /* Program Common_Mode_Restore_Time in upstream device */ - pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_CM_RESTORE_TIME, ctl1); - - /* Program LTR_L1.2_THRESHOLD time in both ports */ - pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_LTR_L12_TH_VALUE | - PCI_L1SS_CTL1_LTR_L12_TH_SCALE, ctl1); - pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1, - PCI_L1SS_CTL1_LTR_L12_TH_VALUE | - PCI_L1SS_CTL1_LTR_L12_TH_SCALE, ctl1); - - if (pl1_2_enables || cl1_2_enables) { - pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1, 0, - pl1_2_enables); - pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1, 0, - cl1_2_enables); - } + cctl1 &= ~(PCI_L1SS_CTL1_CM_RESTORE_TIME | + PCI_L1SS_CTL1_LTR_L12_TH_VALUE | + PCI_L1SS_CTL1_LTR_L12_TH_SCALE); + cctl1 |= (ctl1 & (PCI_L1SS_CTL1_CM_RESTORE_TIME | + PCI_L1SS_CTL1_LTR_L12_TH_VALUE | + PCI_L1SS_CTL1_LTR_L12_TH_SCALE)); + aspm_program_l1ss(child, cctl1, ctl2); } static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) From 4ff116d0d5fd8a025604b0802d93a2d5f4e465d1 Mon Sep 17 00:00:00 2001 From: Vidya Sagar Date: Tue, 13 Sep 2022 18:48:22 +0530 Subject: [PATCH 335/401] PCI/ASPM: Save L1 PM Substates Capability for suspend/resume Previously the L1 PM Substates Control Registers (CTL1 and CTL2) weren't saved and restored during suspend/resume leading to the L1 PM Substates configuration being lost post-resume. Save the L1 PM Substates Control Registers so that the configuration is retained post-resume. [bhelgaas: drop pci_is_pcie() testing; we can rely on pci_configure_ltr() having already done that] Link: https://lore.kernel.org/r/20220913131822.16557-3-vidyas@nvidia.com Signed-off-by: Vidya Sagar Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 7 +++++++ drivers/pci/pci.h | 4 ++++ drivers/pci/pcie/aspm.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 95bc329e74c0..68a49fbaabde 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1663,6 +1663,7 @@ int pci_save_state(struct pci_dev *dev) return i; pci_save_ltr_state(dev); + pci_save_aspm_l1ss_state(dev); pci_save_dpc_state(dev); pci_save_aer_state(dev); pci_save_ptm_state(dev); @@ -1769,6 +1770,7 @@ void pci_restore_state(struct pci_dev *dev) * LTR itself (in the PCIe capability). */ pci_restore_ltr_state(dev); + pci_restore_aspm_l1ss_state(dev); pci_restore_pcie_state(dev); pci_restore_pasid_state(dev); @@ -3485,6 +3487,11 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) if (error) pci_err(dev, "unable to allocate suspend buffer for LTR\n"); + error = pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_L1SS, + 2 * sizeof(u32)); + if (error) + pci_err(dev, "unable to allocate suspend buffer for ASPM-L1SS\n"); + pci_allocate_vc_save_buffers(dev); } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 785f31086313..365a844ec430 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -561,10 +561,14 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active); void pcie_aspm_init_link_state(struct pci_dev *pdev); void pcie_aspm_exit_link_state(struct pci_dev *pdev); void pcie_aspm_powersave_config_link(struct pci_dev *pdev); +void pci_save_aspm_l1ss_state(struct pci_dev *dev); +void pci_restore_aspm_l1ss_state(struct pci_dev *dev); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } +static inline void pci_save_aspm_l1ss_state(struct pci_dev *dev) { } +static inline void pci_restore_aspm_l1ss_state(struct pci_dev *dev) { } #endif #ifdef CONFIG_PCIE_ECRC diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index b4bdadc4ac35..016d222b07c7 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -732,6 +732,43 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state) PCI_L1SS_CTL1_L1SS_MASK, val); } +void pci_save_aspm_l1ss_state(struct pci_dev *dev) +{ + struct pci_cap_saved_state *save_state; + u16 l1ss = dev->l1ss; + u32 *cap; + + if (!l1ss) + return; + + save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS); + if (!save_state) + return; + + cap = (u32 *)&save_state->cap.data[0]; + pci_read_config_dword(dev, l1ss + PCI_L1SS_CTL2, cap++); + pci_read_config_dword(dev, l1ss + PCI_L1SS_CTL1, cap++); +} + +void pci_restore_aspm_l1ss_state(struct pci_dev *dev) +{ + struct pci_cap_saved_state *save_state; + u32 *cap, ctl1, ctl2; + u16 l1ss = dev->l1ss; + + if (!l1ss) + return; + + save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS); + if (!save_state) + return; + + cap = (u32 *)&save_state->cap.data[0]; + ctl2 = *cap++; + ctl1 = *cap; + aspm_program_l1ss(dev, ctl1, ctl2); +} + static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) { pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, From e98ecc6e94f4e6d21c06660b0f336df02836694f Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 26 Sep 2022 11:36:29 +0800 Subject: [PATCH 336/401] cifs: Fix the error length of VALIDATE_NEGOTIATE_INFO message Commit d5c7076b772a ("smb3: add smb3.1.1 to default dialect list") extend the dialects from 3 to 4, but forget to decrease the extended length when specific the dialect, then the message length is larger than expected. This maybe leak some info through network because not initialize the message body. After apply this patch, the VALIDATE_NEGOTIATE_INFO message length is reduced from 28 bytes to 26 bytes. Fixes: d5c7076b772a ("smb3: add smb3.1.1 to default dialect list") Signed-off-by: Zhang Xiaoxu Cc: Acked-by: Paulo Alcantara (SUSE) Reviewed-by: Tom Talpey Signed-off-by: Steve French --- fs/cifs/smb2pdu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 6352ab32c7e7..223056097b54 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1169,9 +1169,9 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) pneg_inbuf->Dialects[0] = cpu_to_le16(server->vals->protocol_id); pneg_inbuf->DialectCount = cpu_to_le16(1); - /* structure is big enough for 3 dialects, sending only 1 */ + /* structure is big enough for 4 dialects, sending only 1 */ inbuflen = sizeof(*pneg_inbuf) - - sizeof(pneg_inbuf->Dialects[0]) * 2; + sizeof(pneg_inbuf->Dialects[0]) * 3; } rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, From d2e81f92e5b76c4c260141928700442876fa4bb3 Mon Sep 17 00:00:00 2001 From: Tom Talpey Date: Fri, 23 Sep 2022 21:53:55 +0000 Subject: [PATCH 337/401] Decrease the number of SMB3 smbdirect client SGEs The client-side SMBDirect layer requires no more than 6 send SGEs and 1 receive SGE. The previous default of 8 send and 8 receive causes smbdirect to fail on the SoftiWARP (siw) provider, and possibly others. Additionally, large numbers of SGEs reduces performance significantly on adapter implementations. Also correct the frmr page count comment (not an SGE count). Acked-by: Paulo Alcantara (SUSE) Signed-off-by: Tom Talpey Signed-off-by: Steve French --- fs/cifs/smbdirect.c | 26 ++++++++++++-------------- fs/cifs/smbdirect.h | 14 +++++++++----- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index 5fbbec22bcc8..f81229721b76 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -99,7 +99,7 @@ int smbd_keep_alive_interval = 120; * User configurable initial values for RDMA transport * The actual values used may be lower and are limited to hardware capabilities */ -/* Default maximum number of SGEs in a RDMA write/read */ +/* Default maximum number of pages in a single RDMA write/read */ int smbd_max_frmr_depth = 2048; /* If payload is less than this byte, use RDMA send/recv not read/write */ @@ -1017,9 +1017,9 @@ static int smbd_post_send_data( { int i; u32 data_length = 0; - struct scatterlist sgl[SMBDIRECT_MAX_SGE]; + struct scatterlist sgl[SMBDIRECT_MAX_SEND_SGE - 1]; - if (n_vec > SMBDIRECT_MAX_SGE) { + if (n_vec > SMBDIRECT_MAX_SEND_SGE - 1) { cifs_dbg(VFS, "Can't fit data to SGL, n_vec=%d\n", n_vec); return -EINVAL; } @@ -1562,17 +1562,15 @@ static struct smbd_connection *_smbd_get_connection( info->max_receive_size = smbd_max_receive_size; info->keep_alive_interval = smbd_keep_alive_interval; - if (info->id->device->attrs.max_send_sge < SMBDIRECT_MAX_SGE) { + if (info->id->device->attrs.max_send_sge < SMBDIRECT_MAX_SEND_SGE || + info->id->device->attrs.max_recv_sge < SMBDIRECT_MAX_RECV_SGE) { log_rdma_event(ERR, - "warning: device max_send_sge = %d too small\n", - info->id->device->attrs.max_send_sge); - log_rdma_event(ERR, "Queue Pair creation may fail\n"); - } - if (info->id->device->attrs.max_recv_sge < SMBDIRECT_MAX_SGE) { - log_rdma_event(ERR, - "warning: device max_recv_sge = %d too small\n", + "device %.*s max_send_sge/max_recv_sge = %d/%d too small\n", + IB_DEVICE_NAME_MAX, + info->id->device->name, + info->id->device->attrs.max_send_sge, info->id->device->attrs.max_recv_sge); - log_rdma_event(ERR, "Queue Pair creation may fail\n"); + goto config_failed; } info->send_cq = NULL; @@ -1598,8 +1596,8 @@ static struct smbd_connection *_smbd_get_connection( qp_attr.qp_context = info; qp_attr.cap.max_send_wr = info->send_credit_target; qp_attr.cap.max_recv_wr = info->receive_credit_max; - qp_attr.cap.max_send_sge = SMBDIRECT_MAX_SGE; - qp_attr.cap.max_recv_sge = SMBDIRECT_MAX_SGE; + qp_attr.cap.max_send_sge = SMBDIRECT_MAX_SEND_SGE; + qp_attr.cap.max_recv_sge = SMBDIRECT_MAX_RECV_SGE; qp_attr.cap.max_inline_data = 0; qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; qp_attr.qp_type = IB_QPT_RC; diff --git a/fs/cifs/smbdirect.h b/fs/cifs/smbdirect.h index a87fca82a796..207ef979cd51 100644 --- a/fs/cifs/smbdirect.h +++ b/fs/cifs/smbdirect.h @@ -91,7 +91,7 @@ struct smbd_connection { /* Memory registrations */ /* Maximum number of RDMA read/write outstanding on this connection */ int responder_resources; - /* Maximum number of SGEs in a RDMA write/read */ + /* Maximum number of pages in a single RDMA write/read on this connection */ int max_frmr_depth; /* * If payload is less than or equal to the threshold, @@ -225,21 +225,25 @@ struct smbd_buffer_descriptor_v1 { __le32 length; } __packed; -/* Default maximum number of SGEs in a RDMA send/recv */ -#define SMBDIRECT_MAX_SGE 16 +/* Maximum number of SGEs used by smbdirect.c in any send work request */ +#define SMBDIRECT_MAX_SEND_SGE 6 + /* The context for a SMBD request */ struct smbd_request { struct smbd_connection *info; struct ib_cqe cqe; - /* the SGE entries for this packet */ - struct ib_sge sge[SMBDIRECT_MAX_SGE]; + /* the SGE entries for this work request */ + struct ib_sge sge[SMBDIRECT_MAX_SEND_SGE]; int num_sge; /* SMBD packet header follows this structure */ u8 packet[]; }; +/* Maximum number of SGEs used by smbdirect.c in any receive work request */ +#define SMBDIRECT_MAX_RECV_SGE 1 + /* The context for a SMBD response */ struct smbd_response { struct smbd_connection *info; From 3c62df55f3306238f36dc19cbe40b5e3d288d116 Mon Sep 17 00:00:00 2001 From: Tom Talpey Date: Fri, 23 Sep 2022 21:53:57 +0000 Subject: [PATCH 338/401] Reduce client smbdirect max receive segment size Reduce client smbdirect max segment receive size to 1364 to match protocol norms. Larger buffers are unnecessary and add significant memory overhead. Acked-by: Paulo Alcantara (SUSE) Signed-off-by: Tom Talpey Signed-off-by: Steve French --- fs/cifs/smbdirect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index f81229721b76..4908ca54610c 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -90,7 +90,7 @@ int smbd_max_send_size = 1364; int smbd_max_fragmented_recv_size = 1024 * 1024; /* The maximum single-message size which can be received */ -int smbd_max_receive_size = 8192; +int smbd_max_receive_size = 1364; /* The timeout to initiate send of a keepalive message on idle */ int smbd_keep_alive_interval = 120; From adeb964d3791e1eea8c4c3ab13549ccc7e411e07 Mon Sep 17 00:00:00 2001 From: Tom Talpey Date: Fri, 23 Sep 2022 21:53:59 +0000 Subject: [PATCH 339/401] Handle variable number of SGEs in client smbdirect send. If/when an outgoing request contains more scatter/gather segments than can be mapped in a single RDMA send work request, use smbdirect fragments to send it in multiple packets. Acked-by: Paulo Alcantara (SUSE) Signed-off-by: Tom Talpey Signed-off-by: Steve French --- fs/cifs/smbdirect.c | 187 ++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 109 deletions(-) diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index 4908ca54610c..6ac424d26fe6 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -1984,10 +1984,11 @@ int smbd_send(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst_array) { struct smbd_connection *info = server->smbd_conn; - struct kvec vec; + struct kvec vecs[SMBDIRECT_MAX_SEND_SGE - 1]; int nvecs; int size; unsigned int buflen, remaining_data_length; + unsigned int offset, remaining_vec_data_length; int start, i, j; int max_iov_size = info->max_send_size - sizeof(struct smbd_data_transfer); @@ -1996,10 +1997,8 @@ int smbd_send(struct TCP_Server_Info *server, struct smb_rqst *rqst; int rqst_idx; - if (info->transport_status != SMBD_CONNECTED) { - rc = -EAGAIN; - goto done; - } + if (info->transport_status != SMBD_CONNECTED) + return -EAGAIN; /* * Add in the page array if there is one. The caller needs to set @@ -2010,125 +2009,95 @@ int smbd_send(struct TCP_Server_Info *server, for (i = 0; i < num_rqst; i++) remaining_data_length += smb_rqst_len(server, &rqst_array[i]); - if (remaining_data_length > info->max_fragmented_send_size) { + if (unlikely(remaining_data_length > info->max_fragmented_send_size)) { + /* assertion: payload never exceeds negotiated maximum */ log_write(ERR, "payload size %d > max size %d\n", remaining_data_length, info->max_fragmented_send_size); - rc = -EINVAL; - goto done; + return -EINVAL; } log_write(INFO, "num_rqst=%d total length=%u\n", num_rqst, remaining_data_length); rqst_idx = 0; -next_rqst: - rqst = &rqst_array[rqst_idx]; - iov = rqst->rq_iov; + do { + rqst = &rqst_array[rqst_idx]; + iov = rqst->rq_iov; - cifs_dbg(FYI, "Sending smb (RDMA): idx=%d smb_len=%lu\n", - rqst_idx, smb_rqst_len(server, rqst)); - for (i = 0; i < rqst->rq_nvec; i++) - dump_smb(iov[i].iov_base, iov[i].iov_len); - - - log_write(INFO, "rqst_idx=%d nvec=%d rqst->rq_npages=%d rq_pagesz=%d rq_tailsz=%d buflen=%lu\n", - rqst_idx, rqst->rq_nvec, rqst->rq_npages, rqst->rq_pagesz, - rqst->rq_tailsz, smb_rqst_len(server, rqst)); - - start = i = 0; - buflen = 0; - while (true) { - buflen += iov[i].iov_len; - if (buflen > max_iov_size) { - if (i > start) { - remaining_data_length -= - (buflen-iov[i].iov_len); - log_write(INFO, "sending iov[] from start=%d i=%d nvecs=%d remaining_data_length=%d\n", - start, i, i - start, - remaining_data_length); - rc = smbd_post_send_data( - info, &iov[start], i-start, - remaining_data_length); - if (rc) - goto done; - } else { - /* iov[start] is too big, break it */ - nvecs = (buflen+max_iov_size-1)/max_iov_size; - log_write(INFO, "iov[%d] iov_base=%p buflen=%d break to %d vectors\n", - start, iov[start].iov_base, - buflen, nvecs); - for (j = 0; j < nvecs; j++) { - vec.iov_base = - (char *)iov[start].iov_base + - j*max_iov_size; - vec.iov_len = max_iov_size; - if (j == nvecs-1) - vec.iov_len = - buflen - - max_iov_size*(nvecs-1); - remaining_data_length -= vec.iov_len; - log_write(INFO, - "sending vec j=%d iov_base=%p iov_len=%zu remaining_data_length=%d\n", - j, vec.iov_base, vec.iov_len, - remaining_data_length); - rc = smbd_post_send_data( - info, &vec, 1, - remaining_data_length); - if (rc) - goto done; - } - i++; - if (i == rqst->rq_nvec) - break; - } - start = i; - buflen = 0; - } else { - i++; - if (i == rqst->rq_nvec) { - /* send out all remaining vecs */ - remaining_data_length -= buflen; - log_write(INFO, "sending iov[] from start=%d i=%d nvecs=%d remaining_data_length=%d\n", - start, i, i - start, - remaining_data_length); - rc = smbd_post_send_data(info, &iov[start], - i-start, remaining_data_length); - if (rc) - goto done; - break; - } + cifs_dbg(FYI, "Sending smb (RDMA): idx=%d smb_len=%lu\n", + rqst_idx, smb_rqst_len(server, rqst)); + remaining_vec_data_length = 0; + for (i = 0; i < rqst->rq_nvec; i++) { + remaining_vec_data_length += iov[i].iov_len; + dump_smb(iov[i].iov_base, iov[i].iov_len); } - log_write(INFO, "looping i=%d buflen=%d\n", i, buflen); - } - /* now sending pages if there are any */ - for (i = 0; i < rqst->rq_npages; i++) { - unsigned int offset; + log_write(INFO, "rqst_idx=%d nvec=%d rqst->rq_npages=%d rq_pagesz=%d rq_tailsz=%d buflen=%lu\n", + rqst_idx, rqst->rq_nvec, + rqst->rq_npages, rqst->rq_pagesz, + rqst->rq_tailsz, smb_rqst_len(server, rqst)); - rqst_page_get_length(rqst, i, &buflen, &offset); - nvecs = (buflen + max_iov_size - 1) / max_iov_size; - log_write(INFO, "sending pages buflen=%d nvecs=%d\n", - buflen, nvecs); - for (j = 0; j < nvecs; j++) { - size = max_iov_size; - if (j == nvecs-1) - size = buflen - j*max_iov_size; - remaining_data_length -= size; - log_write(INFO, "sending pages i=%d offset=%d size=%d remaining_data_length=%d\n", - i, j * max_iov_size + offset, size, - remaining_data_length); - rc = smbd_post_send_page( - info, rqst->rq_pages[i], - j*max_iov_size + offset, - size, remaining_data_length); + start = 0; + offset = 0; + do { + buflen = 0; + i = start; + j = 0; + while (i < rqst->rq_nvec && + j < SMBDIRECT_MAX_SEND_SGE - 1 && + buflen < max_iov_size) { + + vecs[j].iov_base = iov[i].iov_base + offset; + if (buflen + iov[i].iov_len > max_iov_size) { + vecs[j].iov_len = + max_iov_size - iov[i].iov_len; + buflen = max_iov_size; + offset = vecs[j].iov_len; + } else { + vecs[j].iov_len = + iov[i].iov_len - offset; + buflen += vecs[j].iov_len; + offset = 0; + ++i; + } + ++j; + } + + remaining_vec_data_length -= buflen; + remaining_data_length -= buflen; + log_write(INFO, "sending %s iov[%d] from start=%d nvecs=%d remaining_data_length=%d\n", + remaining_vec_data_length > 0 ? + "partial" : "complete", + rqst->rq_nvec, start, j, + remaining_data_length); + + start = i; + rc = smbd_post_send_data(info, vecs, j, remaining_data_length); if (rc) goto done; - } - } + } while (remaining_vec_data_length > 0); - rqst_idx++; - if (rqst_idx < num_rqst) - goto next_rqst; + /* now sending pages if there are any */ + for (i = 0; i < rqst->rq_npages; i++) { + rqst_page_get_length(rqst, i, &buflen, &offset); + nvecs = (buflen + max_iov_size - 1) / max_iov_size; + log_write(INFO, "sending pages buflen=%d nvecs=%d\n", + buflen, nvecs); + for (j = 0; j < nvecs; j++) { + size = min_t(unsigned int, max_iov_size, remaining_data_length); + remaining_data_length -= size; + log_write(INFO, "sending pages i=%d offset=%d size=%d remaining_data_length=%d\n", + i, j * max_iov_size + offset, size, + remaining_data_length); + rc = smbd_post_send_page( + info, rqst->rq_pages[i], + j*max_iov_size + offset, + size, remaining_data_length); + if (rc) + goto done; + } + } + } while (++rqst_idx < num_rqst); done: /* From 0350d7a39c7f8175fca001b6d6a39481da5ef22c Mon Sep 17 00:00:00 2001 From: Tom Talpey Date: Fri, 23 Sep 2022 21:54:00 +0000 Subject: [PATCH 340/401] Fix formatting of client smbdirect RDMA logging Make the debug logging more consistent in formatting of addresses, lengths, and bitfields. Acked-by: Paulo Alcantara (SUSE) Signed-off-by: Tom Talpey Signed-off-by: Steve French --- fs/cifs/smbdirect.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index 6ac424d26fe6..90789aaa6567 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -270,7 +270,7 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) struct smbd_request *request = container_of(wc->wr_cqe, struct smbd_request, cqe); - log_rdma_send(INFO, "smbd_request %p completed wc->status=%d\n", + log_rdma_send(INFO, "smbd_request 0x%p completed wc->status=%d\n", request, wc->status); if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { @@ -448,7 +448,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) struct smbd_connection *info = response->info; int data_length = 0; - log_rdma_recv(INFO, "response=%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%x\n", + log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n", response, response->type, wc->status, wc->opcode, wc->byte_len, wc->pkey_index); @@ -723,7 +723,7 @@ static int smbd_post_send_negotiate_req(struct smbd_connection *info) send_wr.opcode = IB_WR_SEND; send_wr.send_flags = IB_SEND_SIGNALED; - log_rdma_send(INFO, "sge addr=%llx length=%x lkey=%x\n", + log_rdma_send(INFO, "sge addr=0x%llx length=%u lkey=0x%x\n", request->sge[0].addr, request->sge[0].length, request->sge[0].lkey); @@ -792,7 +792,7 @@ static int smbd_post_send(struct smbd_connection *info, for (i = 0; i < request->num_sge; i++) { log_rdma_send(INFO, - "rdma_request sge[%d] addr=%llu length=%u\n", + "rdma_request sge[%d] addr=0x%llx length=%u\n", i, request->sge[i].addr, request->sge[i].length); ib_dma_sync_single_for_device( info->id->device, @@ -1079,7 +1079,7 @@ static int smbd_negotiate(struct smbd_connection *info) response->type = SMBD_NEGOTIATE_RESP; rc = smbd_post_recv(info, response); - log_rdma_event(INFO, "smbd_post_recv rc=%d iov.addr=%llx iov.length=%x iov.lkey=%x\n", + log_rdma_event(INFO, "smbd_post_recv rc=%d iov.addr=0x%llx iov.length=%u iov.lkey=0x%x\n", rc, response->sge.addr, response->sge.length, response->sge.lkey); if (rc) @@ -1539,7 +1539,7 @@ static struct smbd_connection *_smbd_get_connection( if (smbd_send_credit_target > info->id->device->attrs.max_cqe || smbd_send_credit_target > info->id->device->attrs.max_qp_wr) { - log_rdma_event(ERR, "consider lowering send_credit_target = %d. Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", + log_rdma_event(ERR, "consider lowering send_credit_target = %d. Possible CQE overrun, device reporting max_cqe %d max_qp_wr %d\n", smbd_send_credit_target, info->id->device->attrs.max_cqe, info->id->device->attrs.max_qp_wr); @@ -1548,7 +1548,7 @@ static struct smbd_connection *_smbd_get_connection( if (smbd_receive_credit_max > info->id->device->attrs.max_cqe || smbd_receive_credit_max > info->id->device->attrs.max_qp_wr) { - log_rdma_event(ERR, "consider lowering receive_credit_max = %d. Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", + log_rdma_event(ERR, "consider lowering receive_credit_max = %d. Possible CQE overrun, device reporting max_cqe %d max_qp_wr %d\n", smbd_receive_credit_max, info->id->device->attrs.max_cqe, info->id->device->attrs.max_qp_wr); From 68e14569d7e5a1798fcbfd945022a4de86f944a0 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 21 Sep 2022 14:05:53 -0500 Subject: [PATCH 341/401] smb3: add dynamic trace points for tree disconnect Needed this for debugging a failing xfstest. Also change camel case for "treeName" to "tree_name" in tcon struct. Example trace output (from "trace-cmd record -e smb3_tdis*"): umount-9718 [006] ..... 5909.780244: smb3_tdis_enter: xid=206 sid=0xcf38894e tid=0x3d0b8cf8 path=\\localhost\test umount-9718 [007] ..... 5909.780878: smb3_tdis_done: xid=206 sid=0xcf38894e tid=0x3d0b8cf8 Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/cached_dir.c | 2 +- fs/cifs/cifs_debug.c | 4 ++-- fs/cifs/cifs_debug.h | 6 +++--- fs/cifs/cifs_swn.c | 12 ++++++------ fs/cifs/cifsglob.h | 2 +- fs/cifs/connect.c | 13 +++++++------ fs/cifs/dfs_cache.c | 2 +- fs/cifs/dir.c | 8 ++++---- fs/cifs/fscache.c | 2 +- fs/cifs/inode.c | 2 +- fs/cifs/misc.c | 4 ++-- fs/cifs/smb2inode.c | 2 +- fs/cifs/smb2ops.c | 6 +++--- fs/cifs/smb2pdu.c | 16 ++++++++++------ fs/cifs/trace.h | 3 +++ 15 files changed, 46 insertions(+), 38 deletions(-) diff --git a/fs/cifs/cached_dir.c b/fs/cifs/cached_dir.c index b401339f6e73..ca8d7cf2a147 100644 --- a/fs/cifs/cached_dir.c +++ b/fs/cifs/cached_dir.c @@ -160,7 +160,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, if (rc == -EREMCHG) { tcon->need_reconnect = true; pr_warn_once("server share %s deleted\n", - tcon->treeName); + tcon->tree_name); } goto oshr_exit; } diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index c05477e28cff..90850da390ae 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -87,7 +87,7 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon) { __u32 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); - seq_printf(m, "%s Mounts: %d ", tcon->treeName, tcon->tc_count); + seq_printf(m, "%s Mounts: %d ", tcon->tree_name, tcon->tc_count); if (tcon->nativeFileSystem) seq_printf(m, "Type: %s ", tcon->nativeFileSystem); seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d", @@ -601,7 +601,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { i++; - seq_printf(m, "\n%d) %s", i, tcon->treeName); + seq_printf(m, "\n%d) %s", i, tcon->tree_name); if (tcon->need_reconnect) seq_puts(m, "\tDISCONNECTED "); seq_printf(m, "\nSMBs: %d", diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h index ee4ea2b60c0f..d44808263cfb 100644 --- a/fs/cifs/cifs_debug.h +++ b/fs/cifs/cifs_debug.h @@ -108,8 +108,8 @@ do { \ #define cifs_tcon_dbg_func(ratefunc, type, fmt, ...) \ do { \ const char *tn = ""; \ - if (tcon && tcon->treeName) \ - tn = tcon->treeName; \ + if (tcon && tcon->tree_name) \ + tn = tcon->tree_name; \ if ((type) & FYI && cifsFYI & CIFS_INFO) { \ pr_debug_ ## ratefunc("%s: %s " fmt, \ __FILE__, tn, ##__VA_ARGS__); \ @@ -150,7 +150,7 @@ do { \ #define cifs_tcon_dbg(type, fmt, ...) \ do { \ if (0) \ - pr_debug("%s " fmt, tcon->treeName, ##__VA_ARGS__); \ + pr_debug("%s " fmt, tcon->tree_name, ##__VA_ARGS__); \ } while (0) #define cifs_info(fmt, ...) \ diff --git a/fs/cifs/cifs_swn.c b/fs/cifs/cifs_swn.c index 1e4c7cc5287f..7233c6a7e6d7 100644 --- a/fs/cifs/cifs_swn.c +++ b/fs/cifs/cifs_swn.c @@ -256,23 +256,23 @@ static struct cifs_swn_reg *cifs_find_swn_reg(struct cifs_tcon *tcon) const char *share_name; const char *net_name; - net_name = extract_hostname(tcon->treeName); + net_name = extract_hostname(tcon->tree_name); if (IS_ERR(net_name)) { int ret; ret = PTR_ERR(net_name); cifs_dbg(VFS, "%s: failed to extract host name from target '%s': %d\n", - __func__, tcon->treeName, ret); + __func__, tcon->tree_name, ret); return ERR_PTR(-EINVAL); } - share_name = extract_sharename(tcon->treeName); + share_name = extract_sharename(tcon->tree_name); if (IS_ERR(share_name)) { int ret; ret = PTR_ERR(share_name); cifs_dbg(VFS, "%s: failed to extract share name from target '%s': %d\n", - __func__, tcon->treeName, ret); + __func__, tcon->tree_name, ret); kfree(net_name); return ERR_PTR(-EINVAL); } @@ -335,14 +335,14 @@ static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon *tcon) goto fail; } - reg->net_name = extract_hostname(tcon->treeName); + reg->net_name = extract_hostname(tcon->tree_name); if (IS_ERR(reg->net_name)) { ret = PTR_ERR(reg->net_name); cifs_dbg(VFS, "%s: failed to extract host name from target: %d\n", __func__, ret); goto fail_idr; } - reg->share_name = extract_sharename(tcon->treeName); + reg->share_name = extract_sharename(tcon->tree_name); if (IS_ERR(reg->share_name)) { ret = PTR_ERR(reg->share_name); cifs_dbg(VFS, "%s: failed to extract share name from target: %d\n", __func__, ret); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index ae7f571a7dba..ad606f648bdc 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1149,7 +1149,7 @@ struct cifs_tcon { struct list_head openFileList; spinlock_t open_file_lock; /* protects list above */ struct cifs_ses *ses; /* pointer to session associated with */ - char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ + char tree_name[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ char *nativeFileSystem; char *password; /* for share-level security */ __u32 tid; /* The 4 byte tree id */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 7ae6f2c08153..ad81d7d43eaf 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1940,7 +1940,8 @@ void cifs_put_smb_ses(struct cifs_ses *ses) spin_unlock(&ses->ses_lock); cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count); - cifs_dbg(FYI, "%s: ses ipc: %s\n", __func__, ses->tcon_ipc ? ses->tcon_ipc->treeName : "NONE"); + cifs_dbg(FYI, + "%s: ses ipc: %s\n", __func__, ses->tcon_ipc ? ses->tcon_ipc->tree_name : "NONE"); spin_lock(&cifs_tcp_ses_lock); if (--ses->ses_count > 0) { @@ -2293,7 +2294,7 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) { if (tcon->status == TID_EXITING) return 0; - if (strncmp(tcon->treeName, ctx->UNC, MAX_TREE_SIZE)) + if (strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE)) return 0; if (tcon->seal != ctx->seal) return 0; @@ -3989,7 +3990,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses, } bcc_ptr += length + 1; bytes_left -= (length + 1); - strscpy(tcon->treeName, tree, sizeof(tcon->treeName)); + strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name)); /* mostly informational -- no need to fail on error here */ kfree(tcon->nativeFileSystem); @@ -4197,7 +4198,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) ctx->local_nls = cifs_sb->local_nls; ctx->linux_uid = fsuid; ctx->cred_uid = fsuid; - ctx->UNC = master_tcon->treeName; + ctx->UNC = master_tcon->tree_name; ctx->retry = master_tcon->retry; ctx->nocase = master_tcon->nocase; ctx->nohandlecache = master_tcon->nohandlecache; @@ -4663,7 +4664,7 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru /* If it is not dfs or there was no cached dfs referral, then reconnect to same share */ if (!server->current_fullpath || dfs_cache_noreq_find(server->current_fullpath + 1, &ref, &tl)) { - rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, cifs_sb->local_nls); + rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, cifs_sb->local_nls); goto out; } @@ -4707,7 +4708,7 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru tcon->status = TID_IN_TCON; spin_unlock(&tcon->tc_lock); - rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); + rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, nlsc); if (rc) { spin_lock(&tcon->tc_lock); if (tcon->status == TID_IN_TCON) diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index a9b6c3eba6de..e70915ad7541 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -98,7 +98,7 @@ static struct cifs_ses *find_ipc_from_server_path(struct cifs_ses **ses, const c get_ipc_unc(path, unc, sizeof(unc)); for (; *ses; ses++) { - if (!strcasecmp(unc, (*ses)->tcon_ipc->treeName)) + if (!strcasecmp(unc, (*ses)->tcon_ipc->tree_name)) return *ses; } return ERR_PTR(-ENOENT); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 08f7392716e2..f58869306309 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -50,7 +50,7 @@ cifs_build_path_to_root(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_s } if (add_treename) - dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); + dfsplen = strnlen(tcon->tree_name, MAX_TREE_SIZE + 1); else dfsplen = 0; @@ -59,7 +59,7 @@ cifs_build_path_to_root(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_s return full_path; if (dfsplen) - memcpy(full_path, tcon->treeName, dfsplen); + memcpy(full_path, tcon->tree_name, dfsplen); full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb); memcpy(full_path + dfsplen + 1, ctx->prepath, pplen); convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); @@ -93,7 +93,7 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page, return ERR_PTR(-ENOMEM); if (prefix) - dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); + dfsplen = strnlen(tcon->tree_name, MAX_TREE_SIZE + 1); else dfsplen = 0; @@ -123,7 +123,7 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page, } if (dfsplen) { s -= dfsplen; - memcpy(s, tcon->treeName, dfsplen); + memcpy(s, tcon->tree_name, dfsplen); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { int i; for (i = 0; i < dfsplen; i++) { diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index 23ef56f55ce5..a1751b956318 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c @@ -45,7 +45,7 @@ int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) memset(&key, 0, sizeof(key)); - sharename = extract_sharename(tcon->treeName); + sharename = extract_sharename(tcon->tree_name); if (IS_ERR(sharename)) { cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__); return -EINVAL; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index bac08c20f559..3784d3a88053 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -913,7 +913,7 @@ cifs_set_fattr_ino(int xid, } else { /* make an ino by hashing the UNC */ fattr->cf_flags |= CIFS_FATTR_FAKE_ROOT_INO; - fattr->cf_uniqueid = simple_hashstr(tcon->treeName); + fattr->cf_uniqueid = simple_hashstr(tcon->tree_name); } } } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index c6679398fff9..f42812e4c2cd 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -525,7 +525,7 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; cifs_sb->mnt_cifs_serverino_autodisabled = true; cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s\n", - tcon ? tcon->treeName : "new server"); + tcon ? tcon->tree_name : "new server"); cifs_dbg(VFS, "The server doesn't seem to support them properly or the files might be on different servers (DFS)\n"); cifs_dbg(VFS, "Hardlinks will not be recognized on this mount. Consider mounting with the \"noserverino\" option to silence this message.\n"); @@ -1328,7 +1328,7 @@ int cifs_dfs_query_info_nonascii_quirk(const unsigned int xid, char *treename, *dfspath, sep; int treenamelen, linkpathlen, rc; - treename = tcon->treeName; + treename = tcon->tree_name; /* MS-DFSC: All paths in REQ_GET_DFS_REFERRAL and RESP_GET_DFS_REFERRAL * messages MUST be encoded with exactly one leading backslash, not two * leading backslashes. diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index b83f59051b26..bb3e3d5a0cda 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -379,7 +379,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, SMB2_open_free(&rqst[0]); if (rc == -EREMCHG) { - pr_warn_once("server share %s deleted\n", tcon->treeName); + pr_warn_once("server share %s deleted\n", tcon->tree_name); tcon->need_reconnect = true; } diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 421be43af425..f590a9cb6a1a 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1327,7 +1327,7 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon, CIFSMaxBufSize, (char **)&res_key, &ret_data_len); if (rc == -EOPNOTSUPP) { - pr_warn_once("Server share %s does not support copy range\n", tcon->treeName); + pr_warn_once("Server share %s does not support copy range\n", tcon->tree_name); goto req_res_key_exit; } else if (rc) { cifs_tcon_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc); @@ -2289,7 +2289,7 @@ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server) spin_unlock(&tcon->tc_lock); spin_unlock(&cifs_tcp_ses_lock); pr_warn_once("Server share %s deleted.\n", - tcon->treeName); + tcon->tree_name); return; } } @@ -2498,7 +2498,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, if (rc == -EREMCHG) { tcon->need_reconnect = true; pr_warn_once("server share %s deleted\n", - tcon->treeName); + tcon->tree_name); } goto qic_exit; } diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 223056097b54..90ccac18f9f3 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1930,7 +1930,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, tcon->capabilities = rsp->Capabilities; /* we keep caps little endian */ tcon->maximal_access = le32_to_cpu(rsp->MaximalAccess); tcon->tid = le32_to_cpu(rsp->hdr.Id.SyncId.TreeId); - strscpy(tcon->treeName, tree, sizeof(tcon->treeName)); + strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name)); if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) && ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0)) @@ -1973,6 +1973,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) if (!ses || !(ses->server)) return -EIO; + trace_smb3_tdis_enter(xid, tcon->tid, ses->Suid, tcon->tree_name); spin_lock(&ses->chan_lock); if ((tcon->need_reconnect) || (CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses))) { @@ -2004,8 +2005,11 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) rc = cifs_send_recv(xid, ses, ses->server, &rqst, &resp_buf_type, flags, &rsp_iov); cifs_small_buf_release(req); - if (rc) + if (rc) { cifs_stats_fail_inc(tcon, SMB2_TREE_DISCONNECT_HE); + trace_smb3_tdis_err(xid, tcon->tid, ses->Suid, rc); + } + trace_smb3_tdis_done(xid, tcon->tid, ses->Suid); return rc; } @@ -2674,7 +2678,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, req->hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS; rc = alloc_path_with_tree_prefix(©_path, ©_size, &name_len, - tcon->treeName, utf16_path); + tcon->tree_name, utf16_path); if (rc) goto err_free_req; @@ -2816,7 +2820,7 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, req->hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS; rc = alloc_path_with_tree_prefix(©_path, ©_size, &name_len, - tcon->treeName, path); + tcon->tree_name, path); if (rc) return rc; req->NameLength = cpu_to_le16(name_len * 2); @@ -3011,7 +3015,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, oparms->create_options, oparms->desired_access, rc); if (rc == -EREMCHG) { pr_warn_once("server share %s deleted\n", - tcon->treeName); + tcon->tree_name); tcon->need_reconnect = true; } goto creat_exit; @@ -4429,7 +4433,7 @@ smb2_writev_callback(struct mid_q_entry *mid) wdata->bytes, wdata->result); if (wdata->result == -ENOSPC) pr_warn_once("Out of space writing to %s\n", - tcon->treeName); + tcon->tree_name); } else trace_smb3_write_done(0 /* no xid */, wdata->cfile->fid.persistent_fid, diff --git a/fs/cifs/trace.h b/fs/cifs/trace.h index 6b88dc2e364f..110070ba8b04 100644 --- a/fs/cifs/trace.h +++ b/fs/cifs/trace.h @@ -372,6 +372,7 @@ DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_eof_enter); DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_info_compound_enter); DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(delete_enter); DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(mkdir_enter); +DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(tdis_enter); DECLARE_EVENT_CLASS(smb3_inf_compound_done_class, @@ -409,6 +410,7 @@ DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_eof_done); DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_info_compound_done); DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(delete_done); DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(mkdir_done); +DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(tdis_done); DECLARE_EVENT_CLASS(smb3_inf_compound_err_class, @@ -451,6 +453,7 @@ DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_eof_err); DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_info_compound_err); DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(mkdir_err); DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(delete_err); +DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(tdis_err); /* * For logging SMB3 Status code and Command for responses which return errors From aea6794e664a07324288f3d3484b950922baeebd Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 31 Aug 2022 12:49:42 +1000 Subject: [PATCH 342/401] cifs: Make tcon contain a wrapper structure cached_fids instead of cached_fid This wrapper structure will later be expanded to contain a list of fids that are cached and not just the root fid. Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/cached_dir.c | 50 ++++++++++++++++++++++++-------------------- fs/cifs/cached_dir.h | 8 +++++-- fs/cifs/cifsglob.h | 2 +- fs/cifs/misc.c | 6 +++--- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/fs/cifs/cached_dir.c b/fs/cifs/cached_dir.c index ca8d7cf2a147..88d117ddb630 100644 --- a/fs/cifs/cached_dir.c +++ b/fs/cifs/cached_dir.c @@ -52,7 +52,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, dentry = cifs_sb->root; - cfid = tcon->cfid; + cfid = &tcon->cfids->cfid; mutex_lock(&cfid->fid_mutex); if (cfid->is_valid) { cifs_dbg(FYI, "found a cached root file handle\n"); @@ -226,7 +226,7 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon, { struct cached_fid *cfid; - cfid = tcon->cfid; + cfid = &tcon->cfids->cfid; mutex_lock(&cfid->fid_mutex); if (cfid->dentry == dentry) { @@ -320,7 +320,7 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) tcon = tlink_tcon(tlink); if (IS_ERR(tcon)) continue; - cfid = tcon->cfid; + cfid = &tcon->cfids->cfid; mutex_lock(&cfid->fid_mutex); if (cfid->dentry) { dput(cfid->dentry); @@ -336,12 +336,14 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) */ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) { - mutex_lock(&tcon->cfid->fid_mutex); - tcon->cfid->is_valid = false; + struct cached_fid *cfid = &tcon->cfids->cfid; + + mutex_lock(&cfid->fid_mutex); + cfid->is_valid = false; /* cached handle is not valid, so SMB2_CLOSE won't be sent below */ - close_cached_dir_lease_locked(tcon->cfid); - memset(&tcon->cfid->fid, 0, sizeof(struct cifs_fid)); - mutex_unlock(&tcon->cfid->fid_mutex); + close_cached_dir_lease_locked(cfid); + memset(&cfid->fid, 0, sizeof(struct cifs_fid)); + mutex_unlock(&cfid->fid_mutex); } static void @@ -355,34 +357,36 @@ smb2_cached_lease_break(struct work_struct *work) int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]) { - if (tcon->cfid->is_valid && + struct cached_fid *cfid = &tcon->cfids->cfid; + + if (cfid->is_valid && !memcmp(lease_key, - tcon->cfid->fid.lease_key, + cfid->fid.lease_key, SMB2_LEASE_KEY_SIZE)) { - tcon->cfid->time = 0; - INIT_WORK(&tcon->cfid->lease_break, + cfid->time = 0; + INIT_WORK(&cfid->lease_break, smb2_cached_lease_break); queue_work(cifsiod_wq, - &tcon->cfid->lease_break); + &cfid->lease_break); return true; } return false; } -struct cached_fid *init_cached_dir(void) +struct cached_fids *init_cached_dirs(void) { - struct cached_fid *cfid; + struct cached_fids *cfids; - cfid = kzalloc(sizeof(*cfid), GFP_KERNEL); - if (!cfid) + cfids = kzalloc(sizeof(*cfids), GFP_KERNEL); + if (!cfids) return NULL; - INIT_LIST_HEAD(&cfid->dirents.entries); - mutex_init(&cfid->dirents.de_mutex); - mutex_init(&cfid->fid_mutex); - return cfid; + INIT_LIST_HEAD(&cfids->cfid.dirents.entries); + mutex_init(&cfids->cfid.dirents.de_mutex); + mutex_init(&cfids->cfid.fid_mutex); + return cfids; } -void free_cached_dir(struct cifs_tcon *tcon) +void free_cached_dirs(struct cached_fids *cfids) { - kfree(tcon->cfid); + kfree(cfids); } diff --git a/fs/cifs/cached_dir.h b/fs/cifs/cached_dir.h index bd262dc8b179..e430e1102296 100644 --- a/fs/cifs/cached_dir.h +++ b/fs/cifs/cached_dir.h @@ -45,8 +45,12 @@ struct cached_fid { struct cached_dirents dirents; }; -extern struct cached_fid *init_cached_dir(void); -extern void free_cached_dir(struct cifs_tcon *tcon); +struct cached_fids { + struct cached_fid cfid; +}; + +extern struct cached_fids *init_cached_dirs(void); +extern void free_cached_dirs(struct cached_fids *cfids); extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, const char *path, struct cifs_sb_info *cifs_sb, diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index ad606f648bdc..338bc11f682e 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1228,7 +1228,7 @@ struct cifs_tcon { struct fscache_volume *fscache; /* cookie for share */ #endif struct list_head pending_opens; /* list of incomplete opens */ - struct cached_fid *cfid; /* Cached root fid */ + struct cached_fids *cfids; /* BB add field for back pointer to sb struct(s)? */ #ifdef CONFIG_CIFS_DFS_UPCALL struct list_head ulist; /* cache update list */ diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index f42812e4c2cd..20a112c96bae 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -117,8 +117,8 @@ tconInfoAlloc(void) ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL); if (!ret_buf) return NULL; - ret_buf->cfid = init_cached_dir(); - if (!ret_buf->cfid) { + ret_buf->cfids = init_cached_dirs(); + if (!ret_buf->cfids) { kfree(ret_buf); return NULL; } @@ -144,7 +144,7 @@ tconInfoFree(struct cifs_tcon *tcon) cifs_dbg(FYI, "Null buffer passed to tconInfoFree\n"); return; } - free_cached_dir(tcon); + free_cached_dirs(tcon->cfids); atomic_dec(&tconInfoAllocCount); kfree(tcon->nativeFileSystem); kfree_sensitive(tcon->password); From 47fc2491e108f253cf963c50acc59a74d34c7f2b Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 31 Aug 2022 12:49:43 +1000 Subject: [PATCH 343/401] cifs: improve handlecaching Only track the dentry for the root handle Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/cached_dir.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/cifs/cached_dir.c b/fs/cifs/cached_dir.c index 88d117ddb630..211f630cd876 100644 --- a/fs/cifs/cached_dir.c +++ b/fs/cifs/cached_dir.c @@ -47,11 +47,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, if (cifs_sb->root == NULL) return -ENOENT; - if (strlen(path)) + if (!path[0]) + dentry = cifs_sb->root; + else return -ENOENT; - dentry = cifs_sb->root; - cfid = &tcon->cfids->cfid; mutex_lock(&cfid->fid_mutex); if (cfid->is_valid) { @@ -177,7 +177,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, cfid->tcon = tcon; cfid->is_valid = true; cfid->dentry = dentry; - dget(dentry); + if (dentry) + dget(dentry); kref_init(&cfid->refcount); /* BB TBD check to see if oplock level check can be removed below */ From 30f8f37147bc9af794b89e37d42fc858f201e5b0 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 31 Aug 2022 12:49:44 +1000 Subject: [PATCH 344/401] cifs: store a pointer to a fid in the cfid structure instead of the struct also create a constructor that takes a path name and stores it in the fid. Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/cached_dir.c | 63 ++++++++++++++++++++++++++++++++++++++------ fs/cifs/cached_dir.h | 4 ++- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/fs/cifs/cached_dir.c b/fs/cifs/cached_dir.c index 211f630cd876..b705dac383f9 100644 --- a/fs/cifs/cached_dir.c +++ b/fs/cifs/cached_dir.c @@ -11,6 +11,8 @@ #include "smb2proto.h" #include "cached_dir.h" +struct cached_fid *init_cached_dir(const char *path); + /* * Open the and cache a directory handle. * If error then *cfid is not initialized. @@ -52,7 +54,14 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, else return -ENOENT; - cfid = &tcon->cfids->cfid; + cfid = tcon->cfids->cfid; + if (cfid == NULL) { + cfid = init_cached_dir(path); + tcon->cfids->cfid = cfid; + } + if (cfid == NULL) + return -ENOMEM; + mutex_lock(&cfid->fid_mutex); if (cfid->is_valid) { cifs_dbg(FYI, "found a cached root file handle\n"); @@ -227,7 +236,9 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon, { struct cached_fid *cfid; - cfid = &tcon->cfids->cfid; + cfid = tcon->cfids->cfid; + if (cfid == NULL) + return -ENOENT; mutex_lock(&cfid->fid_mutex); if (cfid->dentry == dentry) { @@ -321,7 +332,9 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) tcon = tlink_tcon(tlink); if (IS_ERR(tcon)) continue; - cfid = &tcon->cfids->cfid; + cfid = tcon->cfids->cfid; + if (cfid == NULL) + continue; mutex_lock(&cfid->fid_mutex); if (cfid->dentry) { dput(cfid->dentry); @@ -337,7 +350,10 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) */ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) { - struct cached_fid *cfid = &tcon->cfids->cfid; + struct cached_fid *cfid = tcon->cfids->cfid; + + if (cfid == NULL) + return; mutex_lock(&cfid->fid_mutex); cfid->is_valid = false; @@ -358,7 +374,10 @@ smb2_cached_lease_break(struct work_struct *work) int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]) { - struct cached_fid *cfid = &tcon->cfids->cfid; + struct cached_fid *cfid = tcon->cfids->cfid; + + if (cfid == NULL) + return false; if (cfid->is_valid && !memcmp(lease_key, @@ -374,6 +393,32 @@ int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]) return false; } +struct cached_fid *init_cached_dir(const char *path) +{ + struct cached_fid *cfid; + + cfid = kzalloc(sizeof(*cfid), GFP_KERNEL); + if (!cfid) + return NULL; + cfid->path = kstrdup(path, GFP_KERNEL); + if (!cfid->path) { + kfree(cfid); + return NULL; + } + + INIT_LIST_HEAD(&cfid->dirents.entries); + mutex_init(&cfid->dirents.de_mutex); + mutex_init(&cfid->fid_mutex); + return cfid; +} + +void free_cached_dir(struct cached_fid *cfid) +{ + kfree(cfid->path); + cfid->path = NULL; + kfree(cfid); +} + struct cached_fids *init_cached_dirs(void) { struct cached_fids *cfids; @@ -381,13 +426,15 @@ struct cached_fids *init_cached_dirs(void) cfids = kzalloc(sizeof(*cfids), GFP_KERNEL); if (!cfids) return NULL; - INIT_LIST_HEAD(&cfids->cfid.dirents.entries); - mutex_init(&cfids->cfid.dirents.de_mutex); - mutex_init(&cfids->cfid.fid_mutex); + mutex_init(&cfids->cfid_list_mutex); return cfids; } void free_cached_dirs(struct cached_fids *cfids) { + if (cfids->cfid) { + free_cached_dir(cfids->cfid); + cfids->cfid = NULL; + } kfree(cfids); } diff --git a/fs/cifs/cached_dir.h b/fs/cifs/cached_dir.h index e430e1102296..bdf6c3866653 100644 --- a/fs/cifs/cached_dir.h +++ b/fs/cifs/cached_dir.h @@ -31,6 +31,7 @@ struct cached_dirents { }; struct cached_fid { + const char *path; bool is_valid:1; /* Do we have a useable root fid */ bool file_all_info_is_valid:1; bool has_lease:1; @@ -46,7 +47,8 @@ struct cached_fid { }; struct cached_fids { - struct cached_fid cfid; + struct mutex cfid_list_mutex; + struct cached_fid *cfid; }; extern struct cached_fids *init_cached_dirs(void); From 3afdfb0dd4baed45b7010e672e44c21fa790bace Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 1 Oct 2022 22:52:20 -0500 Subject: [PATCH 345/401] smb3: define missing create contexts Update the list of create contexts to include the three more recent ones and the one used for mounts to Macs. Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/smbfs_common/smb2pdu.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/smbfs_common/smb2pdu.h b/fs/smbfs_common/smb2pdu.h index 2cab413fffee..7d605db3bb3b 100644 --- a/fs/smbfs_common/smb2pdu.h +++ b/fs/smbfs_common/smb2pdu.h @@ -1101,7 +1101,11 @@ struct smb2_change_notify_rsp { #define SMB2_CREATE_REQUEST_LEASE "RqLs" #define SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 "DH2Q" #define SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 "DH2C" -#define SMB2_CREATE_TAG_POSIX "\x93\xAD\x25\x50\x9C\xB4\x11\xE7\xB4\x23\x83\xDE\x96\x8B\xCD\x7C" +#define SMB2_CREATE_TAG_POSIX "\x93\xAD\x25\x50\x9C\xB4\x11\xE7\xB4\x23\x83\xDE\x96\x8B\xCD\x7C" +#define SMB2_CREATE_APP_INSTANCE_ID "\x45\xBC\xA6\x6A\xEF\xA7\xF7\x4A\x90\x08\xFA\x46\x2E\x14\x4D\x74" +#define SMB2_CREATE_APP_INSTANCE_VERSION "\xB9\x82\xD0\xB7\x3B\x56\x07\x4F\xA0\x7B\x52\x4A\x81\x16\xA0\x10" +#define SVHDX_OPEN_DEVICE_CONTEXT "\x9C\xCB\xCF\x9E\x04\xC1\xE6\x43\x98\x0E\x15\x8D\xA1\xF6\xEC\x83" +#define SMB2_CREATE_TAG_AAPL "AAPL" /* Flag (SMB3 open response) values */ #define SMB2_CREATE_FLAG_REPARSEPOINT 0x01 From 19619b43f0319c7a0564f6ff35aca5f62e7cb118 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:42 +0530 Subject: [PATCH 346/401] PCI: qcom-ep: Disable IRQs during driver remove Disable the Global and PERST IRQs during driver remove to avoid getting spurious IRQs after resource deallocation. Link: https://lore.kernel.org/r/20220914075350.7992-5-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 51afd9c547f5..d7a8dd0533b0 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -581,13 +581,13 @@ static irqreturn_t qcom_pcie_ep_perst_irq_thread(int irq, void *data) static int qcom_pcie_ep_enable_irq_resources(struct platform_device *pdev, struct qcom_pcie_ep *pcie_ep) { - int irq, ret; + int ret; - irq = platform_get_irq_byname(pdev, "global"); - if (irq < 0) - return irq; + pcie_ep->global_irq = platform_get_irq_byname(pdev, "global"); + if (pcie_ep->global_irq < 0) + return pcie_ep->global_irq; - ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + ret = devm_request_threaded_irq(&pdev->dev, pcie_ep->global_irq, NULL, qcom_pcie_ep_global_irq_thread, IRQF_ONESHOT, "global_irq", pcie_ep); @@ -604,7 +604,7 @@ static int qcom_pcie_ep_enable_irq_resources(struct platform_device *pdev, "perst_irq", pcie_ep); if (ret) { dev_err(&pdev->dev, "Failed to request PERST IRQ\n"); - disable_irq(irq); + disable_irq(pcie_ep->global_irq); return ret; } @@ -702,6 +702,9 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev) { struct qcom_pcie_ep *pcie_ep = platform_get_drvdata(pdev); + disable_irq(pcie_ep->global_irq); + disable_irq(pcie_ep->perst_irq); + if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED) return 0; From 6dbba2b53c3bcbbee849d2fa8cf6acc973ab2e81 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:43 +0530 Subject: [PATCH 347/401] PCI: qcom-ep: Expose link transition counts via debugfs Qualcomm PCIe controllers have debug registers in the MMIO region that count PCIe link transitions. Expose them over debugfs to userspace to help debug the low power issues. Link: https://lore.kernel.org/r/20220914075350.7992-6-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 60 +++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index d7a8dd0533b0..d4f2437ba735 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -45,6 +46,11 @@ #define PARF_ATU_BASE_ADDR 0x634 #define PARF_ATU_BASE_ADDR_HI 0x638 #define PARF_SRIS_MODE 0x644 +#define PARF_DEBUG_CNT_PM_LINKST_IN_L2 0xc04 +#define PARF_DEBUG_CNT_PM_LINKST_IN_L1 0xc0c +#define PARF_DEBUG_CNT_PM_LINKST_IN_L0S 0xc10 +#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1 0xc84 +#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2 0xc88 #define PARF_DEVICE_TYPE 0x1000 #define PARF_BDF_TO_SID_CFG 0x2c00 @@ -135,12 +141,14 @@ enum qcom_pcie_ep_link_status { * @pci: Designware PCIe controller struct * @parf: Qualcomm PCIe specific PARF register base * @elbi: Designware PCIe specific ELBI register base + * @mmio: MMIO register base * @perst_map: PERST regmap * @mmio_res: MMIO region resource * @core_reset: PCIe Endpoint core reset * @reset: PERST# GPIO * @wake: WAKE# GPIO * @phy: PHY controller block + * @debugfs: PCIe Endpoint Debugfs directory * @clks: PCIe clocks * @num_clks: PCIe clocks count * @perst_en: Flag for PERST enable @@ -154,6 +162,7 @@ struct qcom_pcie_ep { void __iomem *parf; void __iomem *elbi; + void __iomem *mmio; struct regmap *perst_map; struct resource *mmio_res; @@ -161,6 +170,7 @@ struct qcom_pcie_ep { struct gpio_desc *reset; struct gpio_desc *wake; struct phy *phy; + struct dentry *debugfs; struct clk_bulk_data *clks; int num_clks; @@ -446,6 +456,9 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev, pcie_ep->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mmio"); + pcie_ep->mmio = devm_pci_remap_cfg_resource(dev, pcie_ep->mmio_res); + if (IS_ERR(pcie_ep->mmio)) + return PTR_ERR(pcie_ep->mmio); syscon = of_parse_phandle(dev->of_node, "qcom,perst-regs", 0); if (!syscon) { @@ -627,6 +640,37 @@ static int qcom_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, } } +static int qcom_pcie_ep_link_transition_count(struct seq_file *s, void *data) +{ + struct qcom_pcie_ep *pcie_ep = (struct qcom_pcie_ep *) + dev_get_drvdata(s->private); + + seq_printf(s, "L0s transition count: %u\n", + readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L0S)); + + seq_printf(s, "L1 transition count: %u\n", + readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L1)); + + seq_printf(s, "L1.1 transition count: %u\n", + readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1)); + + seq_printf(s, "L1.2 transition count: %u\n", + readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2)); + + seq_printf(s, "L2 transition count: %u\n", + readl_relaxed(pcie_ep->mmio + PARF_DEBUG_CNT_PM_LINKST_IN_L2)); + + return 0; +} + +static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep *pcie_ep) +{ + struct dw_pcie *pci = &pcie_ep->pci; + + debugfs_create_devm_seqfile(pci->dev, "link_transition_count", pcie_ep->debugfs, + qcom_pcie_ep_link_transition_count); +} + static const struct pci_epc_features qcom_pcie_epc_features = { .linkup_notifier = true, .core_init_notifier = true, @@ -659,6 +703,7 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct qcom_pcie_ep *pcie_ep; + char *name; int ret; pcie_ep = devm_kzalloc(dev, sizeof(*pcie_ep), GFP_KERNEL); @@ -690,8 +735,21 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev) if (ret) goto err_disable_resources; + name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node); + if (!name) { + ret = -ENOMEM; + goto err_disable_irqs; + } + + pcie_ep->debugfs = debugfs_create_dir(name, NULL); + qcom_pcie_ep_init_debugfs(pcie_ep); + return 0; +err_disable_irqs: + disable_irq(pcie_ep->global_irq); + disable_irq(pcie_ep->perst_irq); + err_disable_resources: qcom_pcie_disable_resources(pcie_ep); @@ -705,6 +763,8 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev) disable_irq(pcie_ep->global_irq); disable_irq(pcie_ep->perst_irq); + debugfs_remove_recursive(pcie_ep->debugfs); + if (pcie_ep->link_status == QCOM_PCIE_EP_LINK_DISABLED) return 0; From c457ac029e443faa5886f59f849e94701375b80f Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:44 +0530 Subject: [PATCH 348/401] PCI: qcom-ep: Gate Master AXI clock to MHI bus during L1SS During L1SS, gate the Master clock supplied to the MHI bus to save power. Link: https://lore.kernel.org/r/20220914075350.7992-7-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index d4f2437ba735..5502e627e482 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -27,6 +27,7 @@ #define PARF_SYS_CTRL 0x00 #define PARF_DB_CTRL 0x10 #define PARF_PM_CTRL 0x20 +#define PARF_MHI_CLOCK_RESET_CTRL 0x174 #define PARF_MHI_BASE_ADDR_LOWER 0x178 #define PARF_MHI_BASE_ADDR_UPPER 0x17c #define PARF_DEBUG_INT_EN 0x190 @@ -89,6 +90,9 @@ #define PARF_PM_CTRL_READY_ENTR_L23 BIT(2) #define PARF_PM_CTRL_REQ_NOT_ENTR_L1 BIT(5) +/* PARF_MHI_CLOCK_RESET_CTRL fields */ +#define PARF_MSTR_AXI_CLK_EN BIT(1) + /* PARF_AXI_MSTR_RD_HALT_NO_WRITES register fields */ #define PARF_AXI_MSTR_RD_HALT_NO_WRITE_EN BIT(0) @@ -394,6 +398,11 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) pcie_ep->parf + PARF_MHI_BASE_ADDR_LOWER); writel_relaxed(0, pcie_ep->parf + PARF_MHI_BASE_ADDR_UPPER); + /* Gate Master AXI clock to MHI bus during L1SS */ + val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); + val &= ~PARF_MSTR_AXI_CLK_EN; + val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); + dw_pcie_ep_init_notify(&pcie_ep->pci.ep); /* Enable LTSSM */ From 8d0d254b15cc5b7d46d85fb7ab8ecede9575e672 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 30 Sep 2022 16:56:02 -0400 Subject: [PATCH 349/401] nfsd: fix nfsd_file_unhash_and_dispose nfsd_file_unhash_and_dispose() is called for two reasons: We're either shutting down and purging the filecache, or we've gotten a notification about a file delete, so we want to go ahead and unhash it so that it'll get cleaned up when we close. We're either walking the hashtable or doing a lookup in it and we don't take a reference in either case. What we want to do in both cases is to try and unhash the object and put it on the dispose list if that was successful. If it's no longer hashed, then we don't want to touch it, with the assumption being that something else is already cleaning up the sentinel reference. Instead of trying to selectively decrement the refcount in this function, just unhash it, and if that was successful, move it to the dispose list. Then, the disposal routine will just clean that up as usual. Also, just make this a void function, drop the WARN_ON_ONCE, and the comments about deadlocking since the nature of the purported deadlock is no longer clear. Signed-off-by: Jeff Layton Signed-off-by: Chuck Lever --- fs/nfsd/filecache.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index d5c57360b418..640a3c52c056 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -405,22 +405,15 @@ nfsd_file_unhash(struct nfsd_file *nf) return false; } -/* - * Return true if the file was unhashed. - */ -static bool +static void nfsd_file_unhash_and_dispose(struct nfsd_file *nf, struct list_head *dispose) { trace_nfsd_file_unhash_and_dispose(nf); - if (!nfsd_file_unhash(nf)) - return false; - /* keep final reference for nfsd_file_lru_dispose */ - if (refcount_dec_not_one(&nf->nf_ref)) - return true; - - nfsd_file_lru_remove(nf); - list_add(&nf->nf_lru, dispose); - return true; + if (nfsd_file_unhash(nf)) { + /* caller must call nfsd_file_dispose_list() later */ + nfsd_file_lru_remove(nf); + list_add(&nf->nf_lru, dispose); + } } static void @@ -562,8 +555,6 @@ nfsd_file_dispose_list_delayed(struct list_head *dispose) * @lock: LRU list lock (unused) * @arg: dispose list * - * Note this can deadlock with nfsd_file_cache_purge. - * * Return values: * %LRU_REMOVED: @item was removed from the LRU * %LRU_ROTATE: @item is to be moved to the LRU tail @@ -748,8 +739,6 @@ nfsd_file_close_inode(struct inode *inode) * * Walk the LRU list and close any entries that have not been used since * the last scan. - * - * Note this can deadlock with nfsd_file_cache_purge. */ static void nfsd_file_delayed_close(struct work_struct *work) @@ -891,16 +880,12 @@ out_err: goto out; } -/* - * Note this can deadlock with nfsd_file_lru_cb. - */ static void __nfsd_file_cache_purge(struct net *net) { struct rhashtable_iter iter; struct nfsd_file *nf; LIST_HEAD(dispose); - bool del; rhashtable_walk_enter(&nfsd_file_rhash_tbl, &iter); do { @@ -910,14 +895,7 @@ __nfsd_file_cache_purge(struct net *net) while (!IS_ERR_OR_NULL(nf)) { if (net && nf->nf_net != net) continue; - del = nfsd_file_unhash_and_dispose(nf, &dispose); - - /* - * Deadlock detected! Something marked this entry as - * unhased, but hasn't removed it from the hash list. - */ - WARN_ON_ONCE(!del); - + nfsd_file_unhash_and_dispose(nf, &dispose); nf = rhashtable_walk_next(&iter); } From 243a5263014a30436c93ed3f1f864c1da845455e Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 4 Oct 2022 15:41:10 -0400 Subject: [PATCH 350/401] nfsd: rework hashtable handling in nfsd_do_file_acquire nfsd_file is RCU-freed, so we need to hold the rcu_read_lock long enough to get a reference after finding it in the hash. Take the rcu_read_lock() and call rhashtable_lookup directly. Switch to using rhashtable_lookup_insert_key as well, and use the usual retry mechanism if we hit an -EEXIST. Rename the "retry" bool to open_retry, and eliminiate the insert_err goto target. Signed-off-by: Jeff Layton Signed-off-by: Chuck Lever --- fs/nfsd/filecache.c | 52 +++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 640a3c52c056..29a62db155fb 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -1042,9 +1042,10 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, .need = may_flags & NFSD_FILE_MAY_MASK, .net = SVC_NET(rqstp), }; - struct nfsd_file *nf, *new; - bool retry = true; + bool open_retry = true; + struct nfsd_file *nf; __be32 status; + int ret; status = fh_verify(rqstp, fhp, S_IFREG, may_flags|NFSD_MAY_OWNER_OVERRIDE); @@ -1054,35 +1055,33 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, key.cred = get_current_cred(); retry: - /* Avoid allocation if the item is already in cache */ - nf = rhashtable_lookup_fast(&nfsd_file_rhash_tbl, &key, - nfsd_file_rhash_params); + rcu_read_lock(); + nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key, + nfsd_file_rhash_params); if (nf) nf = nfsd_file_get(nf); + rcu_read_unlock(); if (nf) goto wait_for_construction; - new = nfsd_file_alloc(&key, may_flags); - if (!new) { + nf = nfsd_file_alloc(&key, may_flags); + if (!nf) { status = nfserr_jukebox; goto out_status; } - nf = rhashtable_lookup_get_insert_key(&nfsd_file_rhash_tbl, - &key, &new->nf_rhash, - nfsd_file_rhash_params); - if (!nf) { - nf = new; + ret = rhashtable_lookup_insert_key(&nfsd_file_rhash_tbl, + &key, &nf->nf_rhash, + nfsd_file_rhash_params); + if (likely(ret == 0)) goto open_file; - } - if (IS_ERR(nf)) - goto insert_err; - nf = nfsd_file_get(nf); - if (nf == NULL) { - nf = new; - goto open_file; - } - nfsd_file_slab_free(&new->nf_rcu); + + nfsd_file_slab_free(&nf->nf_rcu); + if (ret == -EEXIST) + goto retry; + trace_nfsd_file_insert_err(rqstp, key.inode, may_flags, ret); + status = nfserr_jukebox; + goto out_status; wait_for_construction: wait_on_bit(&nf->nf_flags, NFSD_FILE_PENDING, TASK_UNINTERRUPTIBLE); @@ -1090,11 +1089,11 @@ wait_for_construction: /* Did construction of this file fail? */ if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { trace_nfsd_file_cons_err(rqstp, key.inode, may_flags, nf); - if (!retry) { + if (!open_retry) { status = nfserr_jukebox; goto out; } - retry = false; + open_retry = false; nfsd_file_put_noref(nf); goto retry; } @@ -1142,13 +1141,6 @@ open_file: smp_mb__after_atomic(); wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING); goto out; - -insert_err: - nfsd_file_slab_free(&new->nf_rcu); - trace_nfsd_file_insert_err(rqstp, key.inode, may_flags, PTR_ERR(nf)); - nf = NULL; - status = nfserr_jukebox; - goto out_status; } /** From 9e2a03173d1b4544c1113059e61e3caa7ce5e3a4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 4 Oct 2022 21:58:07 -0500 Subject: [PATCH 351/401] PCI/ASPM: Factor out L1 PM Substates configuration Move L1 PM Substates configuration from pcie_aspm_cap_init() to a new aspm_l1ss_init() function. No functional change intended. Link: https://lore.kernel.org/r/20221005025809.2247547-2-helgaas@kernel.org Signed-off-by: Bjorn Helgaas Reviewed-by: Kuppuswamy Sathyanarayanan --- drivers/pci/pcie/aspm.c | 103 +++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 016d222b07c7..4535228e4a64 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -554,13 +554,65 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link, aspm_program_l1ss(child, cctl1, ctl2); } +static void aspm_l1ss_init(struct pcie_link_state *link) +{ + struct pci_dev *child = link->downstream, *parent = link->pdev; + u32 parent_l1ss_cap, child_l1ss_cap; + u32 parent_l1ss_ctl1 = 0, child_l1ss_ctl1 = 0; + + /* Setup L1 substate */ + pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP, + &parent_l1ss_cap); + pci_read_config_dword(child, child->l1ss + PCI_L1SS_CAP, + &child_l1ss_cap); + + if (!(parent_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS)) + parent_l1ss_cap = 0; + if (!(child_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS)) + child_l1ss_cap = 0; + + /* + * If we don't have LTR for the entire path from the Root Complex + * to this device, we can't use ASPM L1.2 because it relies on the + * LTR_L1.2_THRESHOLD. See PCIe r4.0, secs 5.5.4, 6.18. + */ + if (!child->ltr_path) + child_l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2; + + if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1) + link->aspm_support |= ASPM_STATE_L1_1; + if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2) + link->aspm_support |= ASPM_STATE_L1_2; + if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1) + link->aspm_support |= ASPM_STATE_L1_1_PCIPM; + if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2) + link->aspm_support |= ASPM_STATE_L1_2_PCIPM; + + if (parent_l1ss_cap) + pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, + &parent_l1ss_ctl1); + if (child_l1ss_cap) + pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL1, + &child_l1ss_ctl1); + + if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1) + link->aspm_enabled |= ASPM_STATE_L1_1; + if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2) + link->aspm_enabled |= ASPM_STATE_L1_2; + if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1) + link->aspm_enabled |= ASPM_STATE_L1_1_PCIPM; + if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2) + link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM; + + if (link->aspm_support & ASPM_STATE_L1SS) + aspm_calc_l1ss_info(link, parent_l1ss_cap, child_l1ss_cap); +} + static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) { struct pci_dev *child = link->downstream, *parent = link->pdev; u32 parent_lnkcap, child_lnkcap; u16 parent_lnkctl, child_lnkctl; - u32 parent_l1ss_cap, child_l1ss_cap; - u32 parent_l1ss_ctl1 = 0, child_l1ss_ctl1 = 0; struct pci_bus *linkbus = parent->subordinate; if (blacklist) { @@ -615,52 +667,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1) link->aspm_enabled |= ASPM_STATE_L1; - /* Setup L1 substate */ - pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP, - &parent_l1ss_cap); - pci_read_config_dword(child, child->l1ss + PCI_L1SS_CAP, - &child_l1ss_cap); - - if (!(parent_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS)) - parent_l1ss_cap = 0; - if (!(child_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS)) - child_l1ss_cap = 0; - - /* - * If we don't have LTR for the entire path from the Root Complex - * to this device, we can't use ASPM L1.2 because it relies on the - * LTR_L1.2_THRESHOLD. See PCIe r4.0, secs 5.5.4, 6.18. - */ - if (!child->ltr_path) - child_l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2; - - if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1) - link->aspm_support |= ASPM_STATE_L1_1; - if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2) - link->aspm_support |= ASPM_STATE_L1_2; - if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1) - link->aspm_support |= ASPM_STATE_L1_1_PCIPM; - if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2) - link->aspm_support |= ASPM_STATE_L1_2_PCIPM; - - if (parent_l1ss_cap) - pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, - &parent_l1ss_ctl1); - if (child_l1ss_cap) - pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL1, - &child_l1ss_ctl1); - - if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1) - link->aspm_enabled |= ASPM_STATE_L1_1; - if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2) - link->aspm_enabled |= ASPM_STATE_L1_2; - if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1) - link->aspm_enabled |= ASPM_STATE_L1_1_PCIPM; - if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2) - link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM; - - if (link->aspm_support & ASPM_STATE_L1SS) - aspm_calc_l1ss_info(link, parent_l1ss_cap, child_l1ss_cap); + aspm_l1ss_init(link); /* Save default state */ link->aspm_default = link->aspm_enabled; From cfc0028627cadfa271fab0290f18731193d63d87 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 4 Oct 2022 21:58:08 -0500 Subject: [PATCH 352/401] PCI/ASPM: Ignore L1 PM Substates if device lacks capability 187f91db8237 ("PCI/ASPM: Remove struct aspm_register_info.l1ss_cap") inadvertently removed a check for existence of the L1 PM Substates (L1SS) Capability before reading it. If there is no L1SS Capability, this means we mistakenly read PCI_COMMAND and PCI_STATUS (config address 0x04) and interpret that as the PCI_L1SS_CAP register, so we may incorrectly configure L1SS. Make sure the L1SS Capability exists before trying to read it. Fixes: 187f91db8237 ("PCI/ASPM: Remove struct aspm_register_info.l1ss_cap") Link: https://lore.kernel.org/r/20221005025809.2247547-3-helgaas@kernel.org Signed-off-by: Bjorn Helgaas Reviewed-by: Kuppuswamy Sathyanarayanan --- drivers/pci/pcie/aspm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 4535228e4a64..f12d117f44e0 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -560,6 +560,9 @@ static void aspm_l1ss_init(struct pcie_link_state *link) u32 parent_l1ss_cap, child_l1ss_cap; u32 parent_l1ss_ctl1 = 0, child_l1ss_ctl1 = 0; + if (!parent->l1ss || !child->l1ss) + return; + /* Setup L1 substate */ pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP, &parent_l1ss_cap); From 7afeb84d14eaaebb71f5c558ed57ca858e4304e7 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 4 Oct 2022 21:58:09 -0500 Subject: [PATCH 353/401] PCI/ASPM: Correct LTR_L1.2_THRESHOLD computation 80d7d7a904fa ("PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device characteristics") replaced a fixed value (163840ns) with one computed from T_POWER_OFF, Common_Mode_Restore_Time, etc., but it encoded the LTR_L1.2_THRESHOLD value incorrectly. This is especially a problem for small thresholds, e.g., 63ns fell into the "threshold_ns < 1024" case and was encoded as 32ns: LTR_L1.2_THRESHOLD_Scale = 1 (multiplier is 32ns) LTR_L1.2_THRESHOLD_Value = 63 >> 5 = 1 LTR_L1.2_THRESHOLD = multiplier * value = 32ns * 1 = 32ns Correct the algorithm to encode all times of 1023ns (0x3ff) or smaller exactly and larger times conservatively (the encoded threshold is never smaller than was requested). This reduces the chance of entering L1.2 when the device can't tolerate the exit latency. Fixes: 80d7d7a904fa ("PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device characteristics") Link: https://lore.kernel.org/r/20221005025809.2247547-4-helgaas@kernel.org Signed-off-by: Bjorn Helgaas Reviewed-by: Kuppuswamy Sathyanarayanan --- drivers/pci/pcie/aspm.c | 49 +++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index f12d117f44e0..53a1fa306e1e 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -350,29 +351,43 @@ static u32 calc_l1ss_pwron(struct pci_dev *pdev, u32 scale, u32 val) return 0; } +/* + * Encode an LTR_L1.2_THRESHOLD value for the L1 PM Substates Control 1 + * register. Ports enter L1.2 when the most recent LTR value is greater + * than or equal to LTR_L1.2_THRESHOLD, so we round up to make sure we + * don't enter L1.2 too aggressively. + * + * See PCIe r6.0, sec 5.5.1, 6.18, 7.8.3.3. + */ static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value) { - u32 threshold_ns = threshold_us * 1000; + u64 threshold_ns = (u64) threshold_us * 1000; - /* See PCIe r3.1, sec 7.33.3 and sec 6.18 */ - if (threshold_ns < 32) { - *scale = 0; + /* + * LTR_L1.2_THRESHOLD_Value ("value") is a 10-bit field with max + * value of 0x3ff. + */ + if (threshold_ns <= 0x3ff * 1) { + *scale = 0; /* Value times 1ns */ *value = threshold_ns; - } else if (threshold_ns < 1024) { - *scale = 1; - *value = threshold_ns >> 5; - } else if (threshold_ns < 32768) { - *scale = 2; - *value = threshold_ns >> 10; - } else if (threshold_ns < 1048576) { - *scale = 3; - *value = threshold_ns >> 15; - } else if (threshold_ns < 33554432) { - *scale = 4; - *value = threshold_ns >> 20; + } else if (threshold_ns <= 0x3ff * 32) { + *scale = 1; /* Value times 32ns */ + *value = roundup(threshold_ns, 32) / 32; + } else if (threshold_ns <= 0x3ff * 1024) { + *scale = 2; /* Value times 1024ns */ + *value = roundup(threshold_ns, 1024) / 1024; + } else if (threshold_ns <= 0x3ff * 32768) { + *scale = 3; /* Value times 32768ns */ + *value = roundup(threshold_ns, 32768) / 32768; + } else if (threshold_ns <= 0x3ff * 1048576) { + *scale = 4; /* Value times 1048576ns */ + *value = roundup(threshold_ns, 1048576) / 1048576; + } else if (threshold_ns <= 0x3ff * (u64) 33554432) { + *scale = 5; /* Value times 33554432ns */ + *value = roundup(threshold_ns, 33554432) / 33554432; } else { *scale = 5; - *value = threshold_ns >> 25; + *value = 0x3ff; /* Max representable value */ } } From 91fa127794ac1c48069479b9d45eb4c7378c0e30 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 16 Sep 2022 14:44:48 -0600 Subject: [PATCH 354/401] PCI: Expose PCIe Resizable BAR support via sysfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a simple sysfs interface to Resizable BAR support, largely for the purposes of assigning such devices to a VM through VFIO. Resizable BARs present a difficult feature to expose to a VM through emulation, as resizing a BAR is done on the host. It can fail, and often does, but we have no means via emulation of a PCIe REBAR capability to handle the error cases. A vfio-pci specific ioctl interface is also cumbersome as there are often multiple devices within the same bridge aperture and handling them is a challenge. In the interface proposed here, expanding a BAR potentially requires such devices to be soft-removed during the resize operation and rescanned after, in order for all the necessary resources to be released. A pci-sysfs interface is also more universal than a vfio specific interface. Please see the ABI documentation update for usage. Link: https://lore.kernel.org/r/166336088796.3597940.14973499936692558556.stgit@omen Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas Reviewed-by: Christian König Cc: Krzysztof Wilczyński --- Documentation/ABI/testing/sysfs-bus-pci | 33 ++++++++ drivers/pci/pci-sysfs.c | 108 ++++++++++++++++++++++++ 2 files changed, 141 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 6fc2c2efe8ab..840727fc75dc 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -457,3 +457,36 @@ Description: The file is writable if the PF is bound to a driver that implements ->sriov_set_msix_vec_count(). + +What: /sys/bus/pci/devices/.../resourceN_resize +Date: September 2022 +Contact: Alex Williamson +Description: + These files provide an interface to PCIe Resizable BAR support. + A file is created for each BAR resource (N) supported by the + PCIe Resizable BAR extended capability of the device. Reading + each file exposes the bitmap of available resource sizes: + + # cat resource1_resize + 00000000000001c0 + + The bitmap represents supported resource sizes for the BAR, + where bit0 = 1MB, bit1 = 2MB, bit2 = 4MB, etc. In the above + example the device supports 64MB, 128MB, and 256MB BAR sizes. + + When writing the file, the user provides the bit position of + the desired resource size, for example: + + # echo 7 > resource1_resize + + This indicates to set the size value corresponding to bit 7, + 128MB. The resulting size is 2 ^ (bit# + 20). This definition + matches the PCIe specification of this capability. + + In order to make use of resource resizing, all PCI drivers must + be unbound from the device and peer devices under the same + parent bridge may need to be soft removed. In the case of + VGA devices, writing a resize value will remove low level + console drivers from the device. Raw users of pci-sysfs + resourceN attributes must be terminated prior to resizing. + Success of the resizing operation is not guaranteed. diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index fc804e08e3cb..0a2eeb82cebd 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "pci.h" static int sysfs_initialized; /* = 0 */ @@ -1373,6 +1374,112 @@ static const struct attribute_group pci_dev_reset_attr_group = { .is_visible = pci_dev_reset_attr_is_visible, }; +#define pci_dev_resource_resize_attr(n) \ +static ssize_t resource##n##_resize_show(struct device *dev, \ + struct device_attribute *attr, \ + char * buf) \ +{ \ + struct pci_dev *pdev = to_pci_dev(dev); \ + ssize_t ret; \ + \ + pci_config_pm_runtime_get(pdev); \ + \ + ret = sysfs_emit(buf, "%016llx\n", \ + (u64)pci_rebar_get_possible_sizes(pdev, n)); \ + \ + pci_config_pm_runtime_put(pdev); \ + \ + return ret; \ +} \ + \ +static ssize_t resource##n##_resize_store(struct device *dev, \ + struct device_attribute *attr,\ + const char *buf, size_t count)\ +{ \ + struct pci_dev *pdev = to_pci_dev(dev); \ + unsigned long size, flags; \ + int ret, i; \ + u16 cmd; \ + \ + if (kstrtoul(buf, 0, &size) < 0) \ + return -EINVAL; \ + \ + device_lock(dev); \ + if (dev->driver) { \ + ret = -EBUSY; \ + goto unlock; \ + } \ + \ + pci_config_pm_runtime_get(pdev); \ + \ + if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) { \ + ret = aperture_remove_conflicting_pci_devices(pdev, \ + "resourceN_resize"); \ + if (ret) \ + goto pm_put; \ + } \ + \ + pci_read_config_word(pdev, PCI_COMMAND, &cmd); \ + pci_write_config_word(pdev, PCI_COMMAND, \ + cmd & ~PCI_COMMAND_MEMORY); \ + \ + flags = pci_resource_flags(pdev, n); \ + \ + pci_remove_resource_files(pdev); \ + \ + for (i = 0; i < PCI_STD_NUM_BARS; i++) { \ + if (pci_resource_len(pdev, i) && \ + pci_resource_flags(pdev, i) == flags) \ + pci_release_resource(pdev, i); \ + } \ + \ + ret = pci_resize_resource(pdev, n, size); \ + \ + pci_assign_unassigned_bus_resources(pdev->bus); \ + \ + if (pci_create_resource_files(pdev)) \ + pci_warn(pdev, "Failed to recreate resource files after BAR resizing\n");\ + \ + pci_write_config_word(pdev, PCI_COMMAND, cmd); \ +pm_put: \ + pci_config_pm_runtime_put(pdev); \ +unlock: \ + device_unlock(dev); \ + \ + return ret ? ret : count; \ +} \ +static DEVICE_ATTR_RW(resource##n##_resize) + +pci_dev_resource_resize_attr(0); +pci_dev_resource_resize_attr(1); +pci_dev_resource_resize_attr(2); +pci_dev_resource_resize_attr(3); +pci_dev_resource_resize_attr(4); +pci_dev_resource_resize_attr(5); + +static struct attribute *resource_resize_attrs[] = { + &dev_attr_resource0_resize.attr, + &dev_attr_resource1_resize.attr, + &dev_attr_resource2_resize.attr, + &dev_attr_resource3_resize.attr, + &dev_attr_resource4_resize.attr, + &dev_attr_resource5_resize.attr, + NULL, +}; + +static umode_t resource_resize_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + + return pci_rebar_get_current_size(pdev, n) < 0 ? 0 : a->mode; +} + +static const struct attribute_group pci_dev_resource_resize_group = { + .attrs = resource_resize_attrs, + .is_visible = resource_resize_is_visible, +}; + int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev) { if (!sysfs_initialized) @@ -1494,6 +1601,7 @@ const struct attribute_group *pci_dev_groups[] = { #ifdef CONFIG_ACPI &pci_dev_acpi_attr_group, #endif + &pci_dev_resource_resize_group, NULL, }; From 4a74e79b543c115bf2b5b7a4b29db139da20b90d Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 4 Oct 2022 20:27:15 +0100 Subject: [PATCH 355/401] i2c: microchip: pci1xxxx: Fix comparison of -EPERM against an unsigned variable The comparison of variable ret with -EPERM is always false because ret is an u8 type. Fix this by making ret an int. Cleans up clang warning: drivers/i2c/busses/i2c-mchp-pci1xxxx.c:714:10: warning: result of comparison of constant -1 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare] Fixes: 361693697249 ("i2c: microchip: pci1xxxx: Add driver for I2C host controller in multifunction endpoint of pci1xxxx switch") Signed-off-by: Colin Ian King Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mchp-pci1xxxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mchp-pci1xxxx.c b/drivers/i2c/busses/i2c-mchp-pci1xxxx.c index f5342201eb6b..09af75921147 100644 --- a/drivers/i2c/busses/i2c-mchp-pci1xxxx.c +++ b/drivers/i2c/busses/i2c-mchp-pci1xxxx.c @@ -708,7 +708,7 @@ static void pci1xxxx_i2c_init(struct pci1xxxx_i2c *i2c) void __iomem *p2 = i2c->i2c_base + SMBUS_STATUS_REG_OFF; void __iomem *p1 = i2c->i2c_base + SMB_GPR_REG; u8 regval; - u8 ret; + int ret; ret = set_sys_lock(i2c); if (ret == -EPERM) { From 8673b6d97a314c2e73352f4a34c1aa9b2730d7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matti=20Lehtim=C3=A4ki?= Date: Sun, 2 Oct 2022 15:28:54 +0300 Subject: [PATCH 356/401] dt-bindings: i2c: qcom,i2c-cci: Document MSM8226 compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSM8226's Camera Control Interface has one master and 3 clocks. Signed-off-by: Matti Lehtimäki Reviewed-by: Krzysztof Kozlowski Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/qcom,i2c-cci.yaml | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml index e51a85848d6e..c0f9537a4bb1 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml @@ -13,6 +13,7 @@ maintainers: properties: compatible: enum: + - qcom,msm8226-cci - qcom,msm8916-cci - qcom,msm8974-cci - qcom,msm8996-cci @@ -27,11 +28,11 @@ properties: const: 0 clocks: - minItems: 4 + minItems: 3 maxItems: 6 clock-names: - minItems: 4 + minItems: 3 maxItems: 6 interrupts: @@ -78,11 +79,28 @@ allOf: compatible: contains: enum: + - qcom,msm8226-cci - qcom,msm8916-cci then: properties: i2c-bus@1: false + - if: + properties: + compatible: + contains: + enum: + - qcom,msm8226-cci + then: + properties: + clocks: + maxItems: 3 + clock-names: + items: + - const: camss_top_ahb + - const: cci_ahb + - const: cci + - if: properties: compatible: From 9ad16f9639646762455bf3ed1e6dfcc6ccc2c099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matti=20Lehtim=C3=A4ki?= Date: Sun, 2 Oct 2022 15:28:55 +0300 Subject: [PATCH 357/401] dt-bindings: i2c: qcom,i2c-cci: Document clocks for MSM8974 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uses same clocks as MSM8226. Signed-off-by: Matti Lehtimäki Reviewed-by: Krzysztof Kozlowski Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml index c0f9537a4bb1..cf9f8fda595f 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml @@ -91,6 +91,7 @@ allOf: contains: enum: - qcom,msm8226-cci + - qcom,msm8974-cci then: properties: clocks: From d046bd1372a5c5448c7c7ba3383a4316fdb32a60 Mon Sep 17 00:00:00 2001 From: Rayyan Ansari Date: Sun, 2 Oct 2022 15:28:56 +0300 Subject: [PATCH 358/401] i2c: qcom-cci: Add MSM8226 compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a compatible for MSM8226's Camera Control Interface, which is similar to the one used on MSM8916. Signed-off-by: Rayyan Ansari Signed-off-by: Matti Lehtimäki Reviewed-by: Loic Poulain Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-qcom-cci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index ea48e6a9cfca..87739fb4388b 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -807,6 +807,7 @@ static const struct cci_data cci_v2_data = { }; static const struct of_device_id cci_dt_match[] = { + { .compatible = "qcom,msm8226-cci", .data = &cci_v1_data}, { .compatible = "qcom,msm8916-cci", .data = &cci_v1_data}, { .compatible = "qcom,msm8974-cci", .data = &cci_v1_5_data}, { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data}, From 301c8f5c32c8fb79c67539bc23972dc3ef48024c Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 27 Sep 2022 16:56:44 +0300 Subject: [PATCH 359/401] i2c: designware: Fix handling of real but unexpected device interrupts Commit c7b79a752871 ("mfd: intel-lpss: Add Intel Alder Lake PCH-S PCI IDs") caused a regression on certain Gigabyte motherboards for Intel Alder Lake-S where system crashes to NULL pointer dereference in i2c_dw_xfer_msg() when system resumes from S3 sleep state ("deep"). I was able to debug the issue on Gigabyte Z690 AORUS ELITE and made following notes: - Issue happens when resuming from S3 but not when resuming from "s2idle" - PCI device 00:15.0 == i2c_designware.0 is already in D0 state when system enters into pci_pm_resume_noirq() while all other i2c_designware PCI devices are in D3. Devices were runtime suspended and in D3 prior entering into suspend - Interrupt comes after pci_pm_resume_noirq() when device interrupts are re-enabled - According to register dump the interrupt really comes from the i2c_designware.0. Controller is enabled, I2C target address register points to a one detectable I2C device address 0x60 and the DW_IC_RAW_INTR_STAT register START_DET, STOP_DET, ACTIVITY and TX_EMPTY bits are set indicating completed I2C transaction. My guess is that the firmware uses this controller to communicate with an on-board I2C device during resume but does not disable the controller before giving control to an operating system. I was told the UEFI update fixes this but never the less it revealed the driver is not ready to handle TX_EMPTY (or RX_FULL) interrupt when device is supposed to be idle and state variables are not set (especially the dev->msgs pointer which may point to NULL or stale old data). Introduce a new software status flag STATUS_ACTIVE indicating when the controller is active in driver point of view. Now treat all interrupts that occur when is not set as unexpected and mask all interrupts from the controller. Fixes: c7b79a752871 ("mfd: intel-lpss: Add Intel Alder Lake PCH-S PCI IDs") Reported-by: Samuel Clark Link: https://bugzilla.kernel.org/show_bug.cgi?id=215907 Cc: stable@vger.kernel.org # v5.12+ Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-designware-core.h | 7 +++++-- drivers/i2c/busses/i2c-designware-master.c | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 70b80e710990..4d3a3b464ecd 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -126,8 +126,9 @@ * status codes */ #define STATUS_IDLE 0x0 -#define STATUS_WRITE_IN_PROGRESS 0x1 -#define STATUS_READ_IN_PROGRESS 0x2 +#define STATUS_ACTIVE 0x1 +#define STATUS_WRITE_IN_PROGRESS 0x2 +#define STATUS_READ_IN_PROGRESS 0x4 /* * operation modes @@ -334,12 +335,14 @@ void i2c_dw_disable_int(struct dw_i2c_dev *dev); static inline void __i2c_dw_enable(struct dw_i2c_dev *dev) { + dev->status |= STATUS_ACTIVE; regmap_write(dev->map, DW_IC_ENABLE, 1); } static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev) { regmap_write(dev->map, DW_IC_ENABLE, 0); + dev->status &= ~STATUS_ACTIVE; } void __i2c_dw_disable(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 44a94b225ed8..dc3c5a15a95b 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -716,6 +716,19 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) u32 stat; stat = i2c_dw_read_clear_intrbits(dev); + + if (!(dev->status & STATUS_ACTIVE)) { + /* + * Unexpected interrupt in driver point of view. State + * variables are either unset or stale so acknowledge and + * disable interrupts for suppressing further interrupts if + * interrupt really came from this HW (E.g. firmware has left + * the HW active). + */ + regmap_write(dev->map, DW_IC_INTR_MASK, 0); + return 0; + } + if (stat & DW_IC_INTR_TX_ABRT) { dev->cmd_err |= DW_IC_ERR_TX_ABRT; dev->status = STATUS_IDLE; From fd66bd74afe880de4f008f96a795fedee887ff44 Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Tue, 4 Oct 2022 16:31:06 +0700 Subject: [PATCH 360/401] i2c: aspeed: Assert NAK when slave is busy On I2C_SLAVE_WRITE_REQUESTED event, Slave already ACK'ed on the address phase. But as the backend driver is busy and unable to process any request from Master, issue RxCmdLast for Slave to auto send NACK on next incoming byte. Signed-off-by: Quan Nguyen Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-aspeed.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index 185dedfebbac..c64c381b69b7 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -244,6 +244,7 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) u32 command, irq_handled = 0; struct i2c_client *slave = bus->slave; u8 value; + int ret; if (!slave) return 0; @@ -311,7 +312,13 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) break; case ASPEED_I2C_SLAVE_WRITE_REQUESTED: bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED; - i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value); + ret = i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value); + /* + * Slave ACK's on this address phase already but as the backend driver + * returns an errno, the bus driver should nack the next incoming byte. + */ + if (ret < 0) + writel(ASPEED_I2CD_M_S_RX_CMD_LAST, bus->base + ASPEED_I2C_CMD_REG); break; case ASPEED_I2C_SLAVE_WRITE_RECEIVED: i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value); From 689fe57e7ecefd2eeba76c32aa569bb3e1e790d9 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 30 Sep 2022 15:48:24 -0700 Subject: [PATCH 361/401] f2fs: allow direct read for zoned device This reverts dbf8e63f48af ("f2fs: remove device type check for direct IO"), and apply the below first version, since it contributed out-of-order DIO writes. For zoned devices, f2fs forbids direct IO and forces buffered IO to serialize write IOs. However, the constraint does not apply to read IOs. Cc: stable@vger.kernel.org Fixes: dbf8e63f48af ("f2fs: remove device type check for direct IO") Signed-off-by: Eunhee Rho Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b63b482c35a8..1ebc08be958e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4526,7 +4526,12 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, /* disallow direct IO if any of devices has unaligned blksize */ if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize) return true; - + /* + * for blkzoned device, fallback direct IO to buffered IO, so + * all IOs can be serialized by log-structured write. + */ + if (f2fs_sb_has_blkzoned(sbi) && (rw == WRITE)) + return true; if (f2fs_lfs_mode(sbi) && (rw == WRITE)) { if (block_unaligned_IO(inode, iocb, iter)) return true; From 0391632948d9c1394601ae56d0cb25a1630874ed Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:45 +0530 Subject: [PATCH 362/401] PCI: qcom-ep: Disable Master AXI Clock when there is no PCIe traffic The Master AXI clock can be disabled when it is not used i.e., when there is no traffic on the PCIe bus. This helps to save power during idle state. [bhelgaas: tidy and wrap comment] Link: https://lore.kernel.org/r/20220914075350.7992-8-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 5502e627e482..c2585cdaa501 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -105,6 +105,7 @@ /* PARF_SYS_CTRL register fields */ #define PARF_SYS_CTRL_AUX_PWR_DET BIT(4) #define PARF_SYS_CTRL_CORE_CLK_CGC_DIS BIT(6) +#define PARF_SYS_CTRL_MSTR_ACLK_CGC_DIS BIT(10) #define PARF_SYS_CTRL_SLV_DBI_WAKE_DISABLE BIT(11) /* PARF_DB_CTRL register fields */ @@ -341,8 +342,14 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) val &= ~PARF_Q2A_FLUSH_EN; writel_relaxed(val, pcie_ep->parf + PARF_Q2A_FLUSH); - /* Disable DBI Wakeup, core clock CGC and enable AUX power */ + /* + * Disable Master AXI clock during idle. Do not allow DBI access + * to take the core out of L1. Disable core clock gating that + * gates PIPE clock from propagating to core clock. Report to the + * host that Vaux is present. + */ val = readl_relaxed(pcie_ep->parf + PARF_SYS_CTRL); + val &= ~PARF_SYS_CTRL_MSTR_ACLK_CGC_DIS; val |= PARF_SYS_CTRL_SLV_DBI_WAKE_DISABLE | PARF_SYS_CTRL_CORE_CLK_CGC_DIS | PARF_SYS_CTRL_AUX_PWR_DET; From 299915d6bee257880139528cd3d293707717eca5 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:46 +0530 Subject: [PATCH 363/401] dt-bindings: PCI: qcom-ep: Make PERST separation optional PERST separation is an optional debug feature used to collect the crash dump from the PCIe endpoint devices by the PCIe host when the endpoint crashes. This feature keeps the PCIe link up by separating the PCIe IP block from the SoC reset logic. Remove the corresponding property "qcom,perst-regs" from the required properties list. Link: https://lore.kernel.org/r/20220914075350.7992-9-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Acked-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml index 3d23599e5e91..b728ede3f09f 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml @@ -105,7 +105,6 @@ required: - reg-names - clocks - clock-names - - qcom,perst-regs - interrupts - interrupt-names - reset-gpios From aa4b1753625ce97a703e71928f67bac07d9d2b55 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:47 +0530 Subject: [PATCH 364/401] PCI: qcom-ep: Make PERST separation optional PERST separation is an optional debug feature used to collect the crash dump from the PCIe endpoint devices by the PCIe host when the endpoint crashes. This feature keeps the PCIe link up by separating the PCIe IP block from the SoC reset logic. Make the property optional in the driver. Link: https://lore.kernel.org/r/20220914075350.7992-10-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index c2585cdaa501..b11d26e50aa2 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -220,8 +220,10 @@ static int qcom_pcie_ep_core_reset(struct qcom_pcie_ep *pcie_ep) */ static void qcom_pcie_ep_configure_tcsr(struct qcom_pcie_ep *pcie_ep) { - regmap_write(pcie_ep->perst_map, pcie_ep->perst_en, 0); - regmap_write(pcie_ep->perst_map, pcie_ep->perst_sep_en, 0); + if (pcie_ep->perst_map) { + regmap_write(pcie_ep->perst_map, pcie_ep->perst_en, 0); + regmap_write(pcie_ep->perst_map, pcie_ep->perst_sep_en, 0); + } } static int qcom_pcie_dw_link_up(struct dw_pcie *pci) @@ -478,8 +480,8 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev, syscon = of_parse_phandle(dev->of_node, "qcom,perst-regs", 0); if (!syscon) { - dev_err(dev, "Failed to parse qcom,perst-regs\n"); - return -EINVAL; + dev_dbg(dev, "PERST separation not available\n"); + return 0; } pcie_ep->perst_map = syscon_node_to_regmap(syscon); From 8dffa879ac79ffb6421dd924e74e6d07b0996207 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:48 +0530 Subject: [PATCH 365/401] dt-bindings: PCI: qcom-ep: Define clocks per platform In preparation for adding the bindings for future SoCs, define the clocks per platform. Link: https://lore.kernel.org/r/20220914075350.7992-11-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Reviewed-by: Krzysztof Kozlowski --- .../devicetree/bindings/pci/qcom,pcie-ep.yaml | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml index b728ede3f09f..bb8e982e69be 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml @@ -9,9 +9,6 @@ title: Qualcomm PCIe Endpoint Controller binding maintainers: - Manivannan Sadhasivam -allOf: - - $ref: "pci-ep.yaml#" - properties: compatible: const: qcom,sdx55-pcie-ep @@ -35,24 +32,10 @@ properties: - const: mmio clocks: - items: - - description: PCIe Auxiliary clock - - description: PCIe CFG AHB clock - - description: PCIe Master AXI clock - - description: PCIe Slave AXI clock - - description: PCIe Slave Q2A AXI clock - - description: PCIe Sleep clock - - description: PCIe Reference clock + maxItems: 7 clock-names: - items: - - const: aux - - const: cfg - - const: bus_master - - const: bus_slave - - const: slave_q2a - - const: sleep - - const: ref + maxItems: 7 qcom,perst-regs: description: Reference to a syscon representing TCSR followed by the two @@ -112,6 +95,35 @@ required: - reset-names - power-domains +allOf: + - $ref: pci-ep.yaml# + - if: + properties: + compatible: + contains: + enum: + - qcom,sdx55-pcie-ep + then: + properties: + clocks: + items: + - description: PCIe Auxiliary clock + - description: PCIe CFG AHB clock + - description: PCIe Master AXI clock + - description: PCIe Slave AXI clock + - description: PCIe Slave Q2A AXI clock + - description: PCIe Sleep clock + - description: PCIe Reference clock + clock-names: + items: + - const: aux + - const: cfg + - const: bus_master + - const: bus_slave + - const: slave_q2a + - const: sleep + - const: ref + unevaluatedProperties: false examples: From 63e445b746aa466525a483b81581e4798eb2f321 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:49 +0530 Subject: [PATCH 366/401] dt-bindings: PCI: qcom-ep: Add support for SM8450 SoC Add devicetree bindings support for SM8450 SoC. Only the clocks are different on this platform, rest is same as SDX55. Link: https://lore.kernel.org/r/20220914075350.7992-12-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Reviewed-by: Rob Herring --- .../devicetree/bindings/pci/qcom,pcie-ep.yaml | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml index bb8e982e69be..977c976ea799 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml @@ -11,7 +11,9 @@ maintainers: properties: compatible: - const: qcom,sdx55-pcie-ep + enum: + - qcom,sdx55-pcie-ep + - qcom,sm8450-pcie-ep reg: items: @@ -32,10 +34,12 @@ properties: - const: mmio clocks: - maxItems: 7 + minItems: 7 + maxItems: 8 clock-names: - maxItems: 7 + minItems: 7 + maxItems: 8 qcom,perst-regs: description: Reference to a syscon representing TCSR followed by the two @@ -124,6 +128,35 @@ allOf: - const: sleep - const: ref + - if: + properties: + compatible: + contains: + enum: + - qcom,sm8450-pcie-ep + then: + properties: + clocks: + items: + - description: PCIe Auxiliary clock + - description: PCIe CFG AHB clock + - description: PCIe Master AXI clock + - description: PCIe Slave AXI clock + - description: PCIe Slave Q2A AXI clock + - description: PCIe Reference clock + - description: PCIe DDRSS SF TBU clock + - description: PCIe AGGRE NOC AXI clock + clock-names: + items: + - const: aux + - const: cfg + - const: bus_master + - const: bus_slave + - const: slave_q2a + - const: ref + - const: ddrss_sf_tbu + - const: aggre_noc_axi + unevaluatedProperties: false examples: From 867ec26c16064b271b1d5fd292a1610ed3a754ec Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Wed, 14 Sep 2022 13:23:50 +0530 Subject: [PATCH 367/401] PCI: qcom-ep: Add support for SM8450 SoC Add support for SM8450 SoC to the Qualcomm PCIe Endpoint Controller driver. The driver uses the same config as the existing SDX55 chipset, so additional settings are not required. Link: https://lore.kernel.org/r/20220914075350.7992-13-manivannan.sadhasivam@linaro.org Signed-off-by: Manivannan Sadhasivam Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index b11d26e50aa2..464e5ca638be 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -793,6 +793,7 @@ static int qcom_pcie_ep_remove(struct platform_device *pdev) static const struct of_device_id qcom_pcie_ep_match[] = { { .compatible = "qcom,sdx55-pcie-ep", }, + { .compatible = "qcom,sm8450-pcie-ep", }, { } }; MODULE_DEVICE_TABLE(of, qcom_pcie_ep_match); From 94f0b955e4ed610e4ee93ee72b88c4415bed685d Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 29 Apr 2022 16:07:40 +0800 Subject: [PATCH 368/401] PCI: qcom-ep: Check platform_get_resource_byname() return value If platform_get_resource_byname() fails, 'mmio_res' will be set to NULL pointer, which causes a NULL pointer dereference when it is used in qcom_pcie_perst_deassert(). Check the return value to prevent it. Link: https://lore.kernel.org/r/20220429080740.1294797-1-yangyingliang@huawei.com Fixes: f55fee56a631 ("PCI: qcom-ep: Add Qualcomm PCIe Endpoint controller driver") Signed-off-by: Yang Yingliang Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Reviewed-by: Andrew Halaney --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 464e5ca638be..6d0d1b759ca2 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -474,6 +474,11 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev, pcie_ep->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mmio"); + if (!pcie_ep->mmio_res) { + dev_err(dev, "Failed to get mmio resource\n"); + return -EINVAL; + } + pcie_ep->mmio = devm_pci_remap_cfg_resource(dev, pcie_ep->mmio_res); if (IS_ERR(pcie_ep->mmio)) return PTR_ERR(pcie_ep->mmio); From 4659f01e3cd94f64d9bd06764ace2ef8fe1b6227 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 1 Oct 2022 11:44:08 -0500 Subject: [PATCH 369/401] smb3: do not log confusing message when server returns no network interfaces Some servers can return an empty network interface list so, unless multichannel is requested, no need to log an error for this, and when multichannel is requested on mount but no interfaces, log something less confusing. For this case change parse_server_interfaces: malformed interface info to empty network interface list returned by server localhost Also do not relog this error every ten minutes (only log on mount, once) Cc: Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 2 +- fs/cifs/connect.c | 2 +- fs/cifs/smb2ops.c | 23 ++++++++++++++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 3bc94bcc7177..71386978858e 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -639,7 +639,7 @@ cifs_chan_is_iface_active(struct cifs_ses *ses, int cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server); int -SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon); +SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount); void extract_unc_hostname(const char *unc, const char **h, size_t *len); int copy_path_name(char *dst, const char *src); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ad81d7d43eaf..93e59b3b36c7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -155,7 +155,7 @@ static void smb2_query_server_interfaces(struct work_struct *work) /* * query server network interfaces, in case they change */ - rc = SMB3_request_interfaces(0, tcon); + rc = SMB3_request_interfaces(0, tcon, false); if (rc) { cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n", __func__, rc); diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index f590a9cb6a1a..10f9ef68e510 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -512,8 +512,7 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) static int parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, - size_t buf_len, - struct cifs_ses *ses) + size_t buf_len, struct cifs_ses *ses, bool in_mount) { struct network_interface_info_ioctl_rsp *p; struct sockaddr_in *addr4; @@ -543,6 +542,20 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, } spin_unlock(&ses->iface_lock); + /* + * Samba server e.g. can return an empty interface list in some cases, + * which would only be a problem if we were requesting multichannel + */ + if (bytes_left == 0) { + /* avoid spamming logs every 10 minutes, so log only in mount */ + if ((ses->chan_max > 1) && in_mount) + cifs_dbg(VFS, + "empty network interface list returned by server %s\n", + ses->server->hostname); + rc = -EINVAL; + goto out; + } + while (bytes_left >= sizeof(*p)) { memset(&tmp_iface, 0, sizeof(tmp_iface)); tmp_iface.speed = le64_to_cpu(p->LinkSpeed); @@ -673,7 +686,7 @@ out: } int -SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) +SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount) { int rc; unsigned int ret_data_len = 0; @@ -693,7 +706,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) goto out; } - rc = parse_server_interfaces(out_buf, ret_data_len, ses); + rc = parse_server_interfaces(out_buf, ret_data_len, ses, in_mount); if (rc) goto out; @@ -729,7 +742,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return; - SMB3_request_interfaces(xid, tcon); + SMB3_request_interfaces(xid, tcon, true /* called during mount */); SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, FS_ATTRIBUTE_INFORMATION); From 943deb6066538aeb5417eae5fdc222defdcb9949 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 4 Oct 2022 20:51:39 -0500 Subject: [PATCH 370/401] cifs: Replace a couple of one-element arrays with flexible-array members One-element arrays are deprecated, and we are replacing them with flexible array members instead. So, replace one-element arrays with flexible-array member in structs negotiate_req and extended_response, and refactor the rest of the code, accordingly. Also, make use of the DECLARE_FLEX_ARRAY() helper to declare flexible array member EncryptionKey in union u. This new helper allows for flexible-array members in unions. Change pointer notation to proper array notation in a call to memcpy() where flexible-array member DialectsArray is being used as destination argument. Important to mention is that doing a build before/after this patch results in no binary output differences. This helps with the ongoing efforts to tighten the FORTIFY_SOURCE routines on memcpy() and help us make progress towards globally enabling -fstrict-flex-arrays=3 [1]. Link: https://github.com/KSPP/linux/issues/79 Link: https://github.com/KSPP/linux/issues/229 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836 [1] Reviewed-by: Kees Cook Reviewed-by: Ronnie Sahlberg Signed-off-by: Gustavo A. R. Silva Signed-off-by: Steve French --- fs/cifs/cifspdu.h | 7 ++++--- fs/cifs/cifssmb.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index aeba371c4c70..d1abaeea974a 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -483,7 +483,7 @@ put_bcc(__u16 count, struct smb_hdr *hdr) typedef struct negotiate_req { struct smb_hdr hdr; /* wct = 0 */ __le16 ByteCount; - unsigned char DialectsArray[1]; + unsigned char DialectsArray[]; } __attribute__((packed)) NEGOTIATE_REQ; #define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */ @@ -508,13 +508,14 @@ typedef struct negotiate_rsp { __u8 EncryptionKeyLength; __u16 ByteCount; union { - unsigned char EncryptionKey[1]; /* cap extended security off */ + /* cap extended security off */ + DECLARE_FLEX_ARRAY(unsigned char, EncryptionKey); /* followed by Domain name - if extended security is off */ /* followed by 16 bytes of server GUID */ /* then security blob if cap_extended_security negotiated */ struct { unsigned char GUID[SMB1_CLIENT_GUID_SIZE]; - unsigned char SecurityBlob[1]; + unsigned char SecurityBlob[]; } __attribute__((packed)) extended_response; } __attribute__((packed)) u; } __attribute__((packed)) NEGOTIATE_RSP; diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 7aa91e272027..7a808e41b1b8 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -465,7 +465,7 @@ CIFSSMBNegotiate(const unsigned int xid, for (i = 0; i < CIFS_NUM_PROT; i++) { size_t len = strlen(protocols[i].name) + 1; - memcpy(pSMB->DialectsArray+count, protocols[i].name, len); + memcpy(&pSMB->DialectsArray[count], protocols[i].name, len); count += len; } inc_rfc1001_len(pSMB, count); From f5823f5ee36040c2a8b8b36afe0783fe0bd7ad14 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Tue, 4 Oct 2022 11:23:32 +0500 Subject: [PATCH 371/401] cifs: remove initialization value Don't initialize the rc as its value is being overwritten before its use. Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Muhammad Usama Anjum Signed-off-by: Steve French --- fs/cifs/smb2pdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 90ccac18f9f3..40fce3376307 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -873,7 +873,7 @@ SMB2_negotiate(const unsigned int xid, struct smb2_negotiate_rsp *rsp; struct kvec iov[1]; struct kvec rsp_iov; - int rc = 0; + int rc; int resp_buftype; int blob_offset, blob_length; char *security_blob; From 9d157c89c5569f0ef560b7a5b2d7bf59ae98499c Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Thu, 6 Oct 2022 10:01:54 +0200 Subject: [PATCH 372/401] MAINTAINERS: adjust STARFIVE JH7100 PINCTRL DRIVER after file movement Commit ba7fdf88e98a ("pinctrl: Create subdirectory for StarFive drivers") moves pinctrl-starfive.c into its own subdirectory starfive; further, commit ba99b756da17 ("pinctrl: starfive: Rename "pinctrl-starfive" to "pinctrl-starfive-jh7100"") adds the suffix jh7100 to the driver and dt-bindings header file name. These commits however do not adjust the entry in MAINTAINERS. Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a broken reference. Adjust the entries for STARFIVE JH7100 PINCTRL DRIVER after file movement. Signed-off-by: Lukas Bulwahn Reviewed-by: Emil Renner Berthing Link: https://lore.kernel.org/r/20221006080154.5396-1-lukas.bulwahn@gmail.com Signed-off-by: Linus Walleij --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 131299c18f02..0a5f3d67e376 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19386,8 +19386,8 @@ M: Emil Renner Berthing L: linux-gpio@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml -F: drivers/pinctrl/pinctrl-starfive.c -F: include/dt-bindings/pinctrl/pinctrl-starfive.h +F: drivers/pinctrl/starfive/ +F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h STARFIVE JH7100 RESET CONTROLLER DRIVER M: Emil Renner Berthing From ef575281b21e9a34dfae544a187c6aac2ae424a9 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sat, 27 Aug 2022 00:27:46 +0900 Subject: [PATCH 373/401] 9p/trans_fd: always use O_NONBLOCK read/write syzbot is reporting hung task at p9_fd_close() [1], for p9_mux_poll_stop() from p9_conn_destroy() from p9_fd_close() is failing to interrupt already started kernel_read() from p9_fd_read() from p9_read_work() and/or kernel_write() from p9_fd_write() from p9_write_work() requests. Since p9_socket_open() sets O_NONBLOCK flag, p9_mux_poll_stop() does not need to interrupt kernel_read()/kernel_write(). However, since p9_fd_open() does not set O_NONBLOCK flag, but pipe blocks unless signal is pending, p9_mux_poll_stop() needs to interrupt kernel_read()/kernel_write() when the file descriptor refers to a pipe. In other words, pipe file descriptor needs to be handled as if socket file descriptor. We somehow need to interrupt kernel_read()/kernel_write() on pipes. A minimal change, which this patch is doing, is to set O_NONBLOCK flag from p9_fd_open(), for O_NONBLOCK flag does not affect reading/writing of regular files. But this approach changes O_NONBLOCK flag on userspace- supplied file descriptors (which might break userspace programs), and O_NONBLOCK flag could be changed by userspace. It would be possible to set O_NONBLOCK flag every time p9_fd_read()/p9_fd_write() is invoked, but still remains small race window for clearing O_NONBLOCK flag. If we don't want to manipulate O_NONBLOCK flag, we might be able to surround kernel_read()/kernel_write() with set_thread_flag(TIF_SIGPENDING) and recalc_sigpending(). Since p9_read_work()/p9_write_work() works are processed by kernel threads which process global system_wq workqueue, signals could not be delivered from remote threads when p9_mux_poll_stop() from p9_conn_destroy() from p9_fd_close() is called. Therefore, calling set_thread_flag(TIF_SIGPENDING)/recalc_sigpending() every time would be needed if we count on signals for making kernel_read()/kernel_write() non-blocking. Link: https://lkml.kernel.org/r/345de429-a88b-7097-d177-adecf9fed342@I-love.SAKURA.ne.jp Link: https://syzkaller.appspot.com/bug?extid=8b41a1365f1106fd0f33 [1] Reported-by: syzbot Signed-off-by: Tetsuo Handa Tested-by: syzbot Reviewed-by: Christian Schoenebeck [Dominique: add comment at Christian's suggestion] Signed-off-by: Dominique Martinet --- net/9p/trans_fd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 25d422c473e8..98732619d839 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -822,11 +822,14 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd) goto out_free_ts; if (!(ts->rd->f_mode & FMODE_READ)) goto out_put_rd; + /* prevent workers from hanging on IO when fd is a pipe */ + ts->rd->f_flags |= O_NONBLOCK; ts->wr = fget(wfd); if (!ts->wr) goto out_put_rd; if (!(ts->wr->f_mode & FMODE_WRITE)) goto out_put_wr; + ts->wr->f_flags |= O_NONBLOCK; client->trans = ts; client->status = Connected; From 296ab4a813841ba1d5f40b03190fd1bd8f25aab0 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Sun, 4 Sep 2022 20:17:49 +0900 Subject: [PATCH 374/401] net/9p: use a dedicated spinlock for trans_fd Shamelessly copying the explanation from Tetsuo Handa's suggested patch[1] (slightly reworded): syzbot is reporting inconsistent lock state in p9_req_put()[2], for p9_tag_remove() from p9_req_put() from IRQ context is using spin_lock_irqsave() on "struct p9_client"->lock but trans_fd (not from IRQ context) is using spin_lock(). Since the locks actually protect different things in client.c and in trans_fd.c, just replace trans_fd.c's lock by a new one specific to the transport (client.c's protect the idr for fid/tag allocations, while trans_fd.c's protects its own req list and request status field that acts as the transport's state machine) Link: https://lore.kernel.org/r/20220904112928.1308799-1-asmadeus@codewreck.org Link: https://lkml.kernel.org/r/2470e028-9b05-2013-7198-1fdad071d999@I-love.SAKURA.ne.jp [1] Link: https://syzkaller.appspot.com/bug?extid=2f20b523930c32c160cc [2] Reported-by: syzbot Reported-by: Tetsuo Handa Reviewed-by: Christian Schoenebeck Signed-off-by: Dominique Martinet --- net/9p/trans_fd.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 98732619d839..97db11e4cf58 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -91,6 +91,7 @@ struct p9_poll_wait { * @mux_list: list link for mux to manage multiple connections (?) * @client: reference to client instance for this connection * @err: error state + * @req_lock: lock protecting req_list and requests statuses * @req_list: accounting for requests which have been sent * @unsent_req_list: accounting for requests that haven't been sent * @rreq: read request @@ -114,6 +115,7 @@ struct p9_conn { struct list_head mux_list; struct p9_client *client; int err; + spinlock_t req_lock; struct list_head req_list; struct list_head unsent_req_list; struct p9_req_t *rreq; @@ -189,10 +191,10 @@ static void p9_conn_cancel(struct p9_conn *m, int err) p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err); - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (m->err) { - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); return; } @@ -205,7 +207,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err) list_move(&req->req_list, &cancel_list); } - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); @@ -360,7 +362,7 @@ static void p9_read_work(struct work_struct *work) if ((m->rreq) && (m->rc.offset == m->rc.capacity)) { p9_debug(P9_DEBUG_TRANS, "got new packet\n"); m->rreq->rc.size = m->rc.offset; - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (m->rreq->status == REQ_STATUS_SENT) { list_del(&m->rreq->req_list); p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD); @@ -369,14 +371,14 @@ static void p9_read_work(struct work_struct *work) p9_debug(P9_DEBUG_TRANS, "Ignore replies associated with a cancelled request\n"); } else { - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); p9_debug(P9_DEBUG_ERROR, "Request tag %d errored out while we were reading the reply\n", m->rc.tag); err = -EIO; goto error; } - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); m->rc.sdata = NULL; m->rc.offset = 0; m->rc.capacity = 0; @@ -454,10 +456,10 @@ static void p9_write_work(struct work_struct *work) } if (!m->wsize) { - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (list_empty(&m->unsent_req_list)) { clear_bit(Wworksched, &m->wsched); - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); return; } @@ -472,7 +474,7 @@ static void p9_write_work(struct work_struct *work) m->wpos = 0; p9_req_get(req); m->wreq = req; - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); } p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n", @@ -589,6 +591,7 @@ static void p9_conn_create(struct p9_client *client) INIT_LIST_HEAD(&m->mux_list); m->client = client; + spin_lock_init(&m->req_lock); INIT_LIST_HEAD(&m->req_list); INIT_LIST_HEAD(&m->unsent_req_list); INIT_WORK(&m->rq, p9_read_work); @@ -670,10 +673,10 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) if (m->err < 0) return m->err; - spin_lock(&client->lock); + spin_lock(&m->req_lock); req->status = REQ_STATUS_UNSENT; list_add_tail(&req->req_list, &m->unsent_req_list); - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); if (test_and_clear_bit(Wpending, &m->wsched)) n = EPOLLOUT; @@ -688,11 +691,13 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) { + struct p9_trans_fd *ts = client->trans; + struct p9_conn *m = &ts->conn; int ret = 1; p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); - spin_lock(&client->lock); + spin_lock(&m->req_lock); if (req->status == REQ_STATUS_UNSENT) { list_del(&req->req_list); @@ -700,21 +705,24 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) p9_req_put(client, req); ret = 0; } - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); return ret; } static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) { + struct p9_trans_fd *ts = client->trans; + struct p9_conn *m = &ts->conn; + p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); - spin_lock(&client->lock); + spin_lock(&m->req_lock); /* Ignore cancelled request if message has been received * before lock. */ if (req->status == REQ_STATUS_RCVD) { - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); return 0; } @@ -723,7 +731,8 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) */ list_del(&req->req_list); req->status = REQ_STATUS_FLSHD; - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); + p9_req_put(client, req); return 0; From 0664c63af16dceb4b40a9825e738136a2dac0260 Mon Sep 17 00:00:00 2001 From: Xiu Jianfeng Date: Fri, 9 Sep 2022 18:35:46 +0800 Subject: [PATCH 375/401] net/9p: add __init/__exit annotations to module init/exit funcs xen transport was missing annotations Link: https://lkml.kernel.org/r/20220909103546.73015-1-xiujianfeng@huawei.com Signed-off-by: Xiu Jianfeng Signed-off-by: Dominique Martinet --- net/9p/trans_xen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index 41c57d40efb6..b15c64128c3e 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -511,7 +511,7 @@ static struct xenbus_driver xen_9pfs_front_driver = { .otherend_changed = xen_9pfs_front_changed, }; -static int p9_trans_xen_init(void) +static int __init p9_trans_xen_init(void) { int rc; @@ -530,7 +530,7 @@ static int p9_trans_xen_init(void) module_init(p9_trans_xen_init); MODULE_ALIAS_9P("xen"); -static void p9_trans_xen_exit(void) +static void __exit p9_trans_xen_exit(void) { v9fs_unregister_trans(&p9_xen_trans); return xenbus_unregister_driver(&xen_9pfs_front_driver); From a8e633c604476e24d26a636582c0f5bdb421e70d Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Wed, 21 Sep 2022 14:09:21 -0700 Subject: [PATCH 376/401] net/9p: clarify trans_fd parse_opt failure handling This parse_opts will set invalid opts.rfd/wfd in case of failure which we already check, but it is not clear for readers that parse_opts error are handled in p9_fd_create: clarify this by explicitely checking the return value. Link: https://lkml.kernel.org/r/20220921210921.1654735-1-floridsleeves@gmail.com Signed-off-by: Li Zhong [Dominique: reworded commit message to clarify this is NOOP] Signed-off-by: Dominique Martinet --- net/9p/trans_fd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 97db11e4cf58..56a186768750 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -1074,7 +1074,9 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args) int err; struct p9_fd_opts opts; - parse_opts(args, &opts); + err = parse_opts(args, &opts); + if (err < 0) + return err; client->trans_opts.fd.rfd = opts.rfd; client->trans_opts.fd.wfd = opts.wfd; From 8ec071c363da3f45585b338b2037de289379939c Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 4 Oct 2022 09:11:33 +0800 Subject: [PATCH 377/401] f2fs: account swapfile inodes In order to check count of opened swapfile inodes. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 ++ fs/f2fs/debug.c | 4 ++++ fs/f2fs/f2fs.h | 9 ++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 1c82a4a4e861..5f895ddcd64a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3989,6 +3989,7 @@ static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file, if (ret < 0) return ret; + stat_inc_swapfile_inode(inode); set_inode_flag(inode, FI_PIN_FILE); f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); return ret; @@ -3998,6 +3999,7 @@ static void f2fs_swap_deactivate(struct file *file) { struct inode *inode = file_inode(file); + stat_dec_swapfile_inode(inode); clear_inode_flag(inode, FI_PIN_FILE); } #else diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 29cf5b6b2341..7a9dd2319155 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -135,6 +135,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->inline_inode = atomic_read(&sbi->inline_inode); si->inline_dir = atomic_read(&sbi->inline_dir); si->compr_inode = atomic_read(&sbi->compr_inode); + si->swapfile_inode = atomic_read(&sbi->swapfile_inode); si->compr_blocks = atomic64_read(&sbi->compr_blocks); si->append = sbi->im[APPEND_INO].ino_num; si->update = sbi->im[UPDATE_INO].ino_num; @@ -385,6 +386,8 @@ static int stat_show(struct seq_file *s, void *v) si->inline_dir); seq_printf(s, " - Compressed Inode: %u, Blocks: %llu\n", si->compr_inode, si->compr_blocks); + seq_printf(s, " - Swapfile Inode: %u\n", + si->swapfile_inode); seq_printf(s, " - Orphan/Append/Update Inode: %u, %u, %u\n", si->orphans, si->append, si->update); seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n", @@ -607,6 +610,7 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi) atomic_set(&sbi->inline_dir, 0); atomic_set(&sbi->compr_inode, 0); atomic64_set(&sbi->compr_blocks, 0); + atomic_set(&sbi->swapfile_inode, 0); atomic_set(&sbi->inplace_count, 0); for (i = META_CP; i < META_MAX; i++) atomic_set(&sbi->meta_count[i], 0); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 1ebc08be958e..134581defe4a 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1770,6 +1770,7 @@ struct f2fs_sb_info { atomic_t inline_dir; /* # of inline_dentry inodes */ atomic_t compr_inode; /* # of compressed inodes */ atomic64_t compr_blocks; /* # of compressed blocks */ + atomic_t swapfile_inode; /* # of swapfile inodes */ atomic_t max_aw_cnt; /* max # of atomic writes */ unsigned int io_skip_bggc; /* skip background gc for in-flight IO */ unsigned int other_skip_bggc; /* skip background gc for other reasons */ @@ -3876,7 +3877,7 @@ struct f2fs_stat_info { int nr_issued_ckpt, nr_total_ckpt, nr_queued_ckpt; unsigned int cur_ckpt_time, peak_ckpt_time; int inline_xattr, inline_inode, inline_dir, append, update, orphans; - int compr_inode; + int compr_inode, swapfile_inode; unsigned long long compr_blocks; int aw_cnt, max_aw_cnt; unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks; @@ -3965,6 +3966,10 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) (atomic64_add(blocks, &F2FS_I_SB(inode)->compr_blocks)) #define stat_sub_compr_blocks(inode, blocks) \ (atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_blocks)) +#define stat_inc_swapfile_inode(inode) \ + (atomic_inc(&F2FS_I_SB(inode)->swapfile_inode)) +#define stat_dec_swapfile_inode(inode) \ + (atomic_dec(&F2FS_I_SB(inode)->swapfile_inode)) #define stat_inc_meta_count(sbi, blkaddr) \ do { \ if (blkaddr < SIT_I(sbi)->sit_base_addr) \ @@ -4049,6 +4054,8 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi); #define stat_dec_compr_inode(inode) do { } while (0) #define stat_add_compr_blocks(inode, blocks) do { } while (0) #define stat_sub_compr_blocks(inode, blocks) do { } while (0) +#define stat_inc_swapfile_inode(inode) do { } while (0) +#define stat_dec_swapfile_inode(inode) do { } while (0) #define stat_update_max_atomic_write(inode) do { } while (0) #define stat_inc_meta_count(sbi, blkaddr) do { } while (0) #define stat_inc_seg_type(sbi, curseg) do { } while (0) From b4dac1203f39821c6119033cdeebcea83cf45786 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 4 Oct 2022 09:41:02 +0800 Subject: [PATCH 378/401] f2fs: change to use atomic_t type form sbi.atomic_files inode_lock[ATOMIC_FILE] was used for protecting sbi->atomic_files, update atomic_files variable's type to atomic_t instead of unsigned int, then inode_lock[ATOMIC_FILE] can be obsoleted. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/debug.c | 3 ++- fs/f2fs/f2fs.h | 11 ++++++++--- fs/f2fs/file.c | 4 +--- fs/f2fs/segment.c | 6 +----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 7a9dd2319155..a216dcdf6941 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -91,7 +91,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->ndirty_files = sbi->ndirty_inode[FILE_INODE]; si->nquota_files = sbi->nquota_files; si->ndirty_all = sbi->ndirty_inode[DIRTY_META]; - si->aw_cnt = sbi->atomic_files; + si->aw_cnt = atomic_read(&sbi->atomic_files); si->max_aw_cnt = atomic_read(&sbi->max_aw_cnt); si->nr_dio_read = get_pages(sbi, F2FS_DIO_READ); si->nr_dio_write = get_pages(sbi, F2FS_DIO_WRITE); @@ -611,6 +611,7 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi) atomic_set(&sbi->compr_inode, 0); atomic64_set(&sbi->compr_blocks, 0); atomic_set(&sbi->swapfile_inode, 0); + atomic_set(&sbi->atomic_files, 0); atomic_set(&sbi->inplace_count, 0); for (i = META_CP; i < META_MAX; i++) atomic_set(&sbi->meta_count[i], 0); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 134581defe4a..e7e750e6b332 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1257,7 +1257,6 @@ enum inode_type { DIR_INODE, /* for dirty dir inode */ FILE_INODE, /* for dirty regular/symlink inode */ DIRTY_META, /* for all dirtied inode metadata */ - ATOMIC_FILE, /* for all atomic files */ NR_INODE_TYPE, }; @@ -1739,7 +1738,6 @@ struct f2fs_sb_info { unsigned int gc_urgent_high_remaining; /* remaining trial count for GC_URGENT_HIGH */ /* for skip statistic */ - unsigned int atomic_files; /* # of opened atomic file */ unsigned long long skipped_gc_rwsem; /* FG_GC only */ /* threshold for gc trials on pinned files */ @@ -1771,6 +1769,7 @@ struct f2fs_sb_info { atomic_t compr_inode; /* # of compressed inodes */ atomic64_t compr_blocks; /* # of compressed blocks */ atomic_t swapfile_inode; /* # of swapfile inodes */ + atomic_t atomic_files; /* # of opened atomic file */ atomic_t max_aw_cnt; /* max # of atomic writes */ unsigned int io_skip_bggc; /* skip background gc for in-flight IO */ unsigned int other_skip_bggc; /* skip background gc for other reasons */ @@ -3970,6 +3969,10 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) (atomic_inc(&F2FS_I_SB(inode)->swapfile_inode)) #define stat_dec_swapfile_inode(inode) \ (atomic_dec(&F2FS_I_SB(inode)->swapfile_inode)) +#define stat_inc_atomic_inode(inode) \ + (atomic_inc(&F2FS_I_SB(inode)->atomic_files)) +#define stat_dec_atomic_inode(inode) \ + (atomic_dec(&F2FS_I_SB(inode)->atomic_files)) #define stat_inc_meta_count(sbi, blkaddr) \ do { \ if (blkaddr < SIT_I(sbi)->sit_base_addr) \ @@ -3989,7 +3992,7 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) (atomic_inc(&(sbi)->inplace_count)) #define stat_update_max_atomic_write(inode) \ do { \ - int cur = F2FS_I_SB(inode)->atomic_files; \ + int cur = atomic_read(&F2FS_I_SB(inode)->atomic_files); \ int max = atomic_read(&F2FS_I_SB(inode)->max_aw_cnt); \ if (cur > max) \ atomic_set(&F2FS_I_SB(inode)->max_aw_cnt, cur); \ @@ -4056,6 +4059,8 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi); #define stat_sub_compr_blocks(inode, blocks) do { } while (0) #define stat_inc_swapfile_inode(inode) do { } while (0) #define stat_dec_swapfile_inode(inode) do { } while (0) +#define stat_inc_atomic_inode(inode) do { } while (0) +#define stat_dec_atomic_inode(inode) do { } while (0) #define stat_update_max_atomic_write(inode) do { } while (0) #define stat_inc_meta_count(sbi, blkaddr) do { } while (0) #define stat_inc_seg_type(sbi, curseg) do { } while (0) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 7b3ed4a9bb46..ec9ee0f6d502 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2051,9 +2051,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) } f2fs_i_size_write(fi->cow_inode, i_size_read(inode)); - spin_lock(&sbi->inode_lock[ATOMIC_FILE]); - sbi->atomic_files++; - spin_unlock(&sbi->inode_lock[ATOMIC_FILE]); + stat_inc_atomic_inode(inode); set_inode_flag(inode, FI_ATOMIC_FILE); set_inode_flag(fi->cow_inode, FI_COW_FILE); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index d7b13127b0b8..289bcb7ca300 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -187,7 +187,6 @@ bool f2fs_need_SSR(struct f2fs_sb_info *sbi) void f2fs_abort_atomic_write(struct inode *inode, bool clean) { - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode); if (!f2fs_is_atomic_file(inode)) @@ -200,10 +199,7 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean) fi->cow_inode = NULL; release_atomic_write_cnt(inode); clear_inode_flag(inode, FI_ATOMIC_FILE); - - spin_lock(&sbi->inode_lock[ATOMIC_FILE]); - sbi->atomic_files--; - spin_unlock(&sbi->inode_lock[ATOMIC_FILE]); + stat_dec_atomic_inode(inode); } static int __replace_atomic_write_block(struct inode *inode, pgoff_t index, From a4e430c8c8ba96be8c6ec4f2eb108bb8bcbee069 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Tue, 20 Sep 2022 15:10:35 -0300 Subject: [PATCH 379/401] cifs: replace kfree() with kfree_sensitive() for sensitive data Replace kfree with kfree_sensitive, or prepend memzero_explicit() in other cases, when freeing sensitive material that could still be left in memory. Signed-off-by: Enzo Matsumiya Reported-by: kernel test robot Link: https://lore.kernel.org/r/202209201529.ec633796-oliver.sang@intel.com Reviewed-by: Paulo Alcantara (SUSE) Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/cifsencrypt.c | 12 ++++++------ fs/cifs/connect.c | 6 +++--- fs/cifs/fs_context.c | 12 ++++++++++-- fs/cifs/misc.c | 2 +- fs/cifs/sess.c | 24 +++++++++++++++--------- fs/cifs/smb2ops.c | 6 +++--- fs/cifs/smb2pdu.c | 19 ++++++++++++++----- 7 files changed, 52 insertions(+), 29 deletions(-) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 46f5718754f9..d848bc0aac27 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -679,7 +679,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) unlock: cifs_server_unlock(ses->server); setup_ntlmv2_rsp_ret: - kfree(tiblob); + kfree_sensitive(tiblob); return rc; } @@ -753,14 +753,14 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server) server->secmech.ccmaesdecrypt = NULL; } - kfree(server->secmech.sdesccmacaes); + kfree_sensitive(server->secmech.sdesccmacaes); server->secmech.sdesccmacaes = NULL; - kfree(server->secmech.sdeschmacsha256); + kfree_sensitive(server->secmech.sdeschmacsha256); server->secmech.sdeschmacsha256 = NULL; - kfree(server->secmech.sdeschmacmd5); + kfree_sensitive(server->secmech.sdeschmacmd5); server->secmech.sdeschmacmd5 = NULL; - kfree(server->secmech.sdescmd5); + kfree_sensitive(server->secmech.sdescmd5); server->secmech.sdescmd5 = NULL; - kfree(server->secmech.sdescsha512); + kfree_sensitive(server->secmech.sdescsha512); server->secmech.sdescsha512 = NULL; } diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 93e59b3b36c7..40900aace416 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -311,7 +311,7 @@ cifs_abort_connection(struct TCP_Server_Info *server) } server->sequence_number = 0; server->session_estab = false; - kfree(server->session_key.response); + kfree_sensitive(server->session_key.response); server->session_key.response = NULL; server->session_key.len = 0; server->lstrp = jiffies; @@ -1580,7 +1580,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) cifs_crypto_secmech_release(server); - kfree(server->session_key.response); + kfree_sensitive(server->session_key.response); server->session_key.response = NULL; server->session_key.len = 0; kfree(server->hostname); @@ -4135,7 +4135,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, if (ses->auth_key.response) { cifs_dbg(FYI, "Free previous auth_key.response = %p\n", ses->auth_key.response); - kfree(ses->auth_key.response); + kfree_sensitive(ses->auth_key.response); ses->auth_key.response = NULL; ses->auth_key.len = 0; } diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 0e13dec86b25..45119597c765 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -791,6 +791,13 @@ do { \ cifs_sb->ctx->field = NULL; \ } while (0) +#define STEAL_STRING_SENSITIVE(cifs_sb, ctx, field) \ +do { \ + kfree_sensitive(ctx->field); \ + ctx->field = cifs_sb->ctx->field; \ + cifs_sb->ctx->field = NULL; \ +} while (0) + static int smb3_reconfigure(struct fs_context *fc) { struct smb3_fs_context *ctx = smb3_fc2context(fc); @@ -811,7 +818,7 @@ static int smb3_reconfigure(struct fs_context *fc) STEAL_STRING(cifs_sb, ctx, UNC); STEAL_STRING(cifs_sb, ctx, source); STEAL_STRING(cifs_sb, ctx, username); - STEAL_STRING(cifs_sb, ctx, password); + STEAL_STRING_SENSITIVE(cifs_sb, ctx, password); STEAL_STRING(cifs_sb, ctx, domainname); STEAL_STRING(cifs_sb, ctx, nodename); STEAL_STRING(cifs_sb, ctx, iocharset); @@ -1162,7 +1169,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, } break; case Opt_pass: - kfree(ctx->password); + kfree_sensitive(ctx->password); ctx->password = NULL; if (strlen(param->string) == 0) break; @@ -1470,6 +1477,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, return 0; cifs_parse_mount_err: + kfree_sensitive(ctx->password); return -EINVAL; } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 20a112c96bae..72bd1b2b323f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -1119,7 +1119,7 @@ cifs_alloc_hash(const char *name, void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc) { - kfree(*sdesc); + kfree_sensitive(*sdesc); *sdesc = NULL; if (*shash) crypto_free_shash(*shash); diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 3af3b05b6c74..f1c3c6d9146c 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -1213,6 +1213,12 @@ out_free_smb_buf: static void sess_free_buffer(struct sess_data *sess_data) { + int i; + + /* zero the session data before freeing, as it might contain sensitive info (keys, etc) */ + for (i = 0; i < 3; i++) + if (sess_data->iov[i].iov_base) + memzero_explicit(sess_data->iov[i].iov_base, sess_data->iov[i].iov_len); free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base); sess_data->buf0_type = CIFS_NO_BUFFER; @@ -1374,7 +1380,7 @@ out: sess_data->result = rc; sess_data->func = NULL; sess_free_buffer(sess_data); - kfree(ses->auth_key.response); + kfree_sensitive(ses->auth_key.response); ses->auth_key.response = NULL; } @@ -1513,7 +1519,7 @@ out: sess_data->result = rc; sess_data->func = NULL; sess_free_buffer(sess_data); - kfree(ses->auth_key.response); + kfree_sensitive(ses->auth_key.response); ses->auth_key.response = NULL; } @@ -1648,7 +1654,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data) rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses); out_free_ntlmsspblob: - kfree(ntlmsspblob); + kfree_sensitive(ntlmsspblob); out: sess_free_buffer(sess_data); @@ -1658,9 +1664,9 @@ out: } /* Else error. Cleanup */ - kfree(ses->auth_key.response); + kfree_sensitive(ses->auth_key.response); ses->auth_key.response = NULL; - kfree(ses->ntlmssp); + kfree_sensitive(ses->ntlmssp); ses->ntlmssp = NULL; sess_data->func = NULL; @@ -1759,7 +1765,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data) } out_free_ntlmsspblob: - kfree(ntlmsspblob); + kfree_sensitive(ntlmsspblob); out: sess_free_buffer(sess_data); @@ -1767,9 +1773,9 @@ out: rc = sess_establish_session(sess_data); /* Cleanup */ - kfree(ses->auth_key.response); + kfree_sensitive(ses->auth_key.response); ses->auth_key.response = NULL; - kfree(ses->ntlmssp); + kfree_sensitive(ses->ntlmssp); ses->ntlmssp = NULL; sess_data->func = NULL; @@ -1845,7 +1851,7 @@ int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, rc = sess_data->result; out: - kfree(sess_data); + kfree_sensitive(sess_data); return rc; } #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 10f9ef68e510..9a686870e8b7 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4423,11 +4423,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, if (!rc && enc) memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE); - kfree(iv); + kfree_sensitive(iv); free_sg: - kfree(sg); + kfree_sensitive(sg); free_req: - kfree(req); + kfree_sensitive(req); return rc; } diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 40fce3376307..b3c4d2e54eaa 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1345,6 +1345,13 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data) static void SMB2_sess_free_buffer(struct SMB2_sess_data *sess_data) { + int i; + + /* zero the session data before freeing, as it might contain sensitive info (keys, etc) */ + for (i = 0; i < 2; i++) + if (sess_data->iov[i].iov_base) + memzero_explicit(sess_data->iov[i].iov_base, sess_data->iov[i].iov_len); + free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base); sess_data->buf0_type = CIFS_NO_BUFFER; } @@ -1477,6 +1484,8 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data) out_put_spnego_key: key_invalidate(spnego_key); key_put(spnego_key); + if (rc) + kfree_sensitive(ses->auth_key.response); out: sess_data->result = rc; sess_data->func = NULL; @@ -1573,7 +1582,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data) } out: - kfree(ntlmssp_blob); + memzero_explicit(ntlmssp_blob, blob_length); SMB2_sess_free_buffer(sess_data); if (!rc) { sess_data->result = 0; @@ -1581,7 +1590,7 @@ out: return; } out_err: - kfree(ses->ntlmssp); + kfree_sensitive(ses->ntlmssp); ses->ntlmssp = NULL; sess_data->result = rc; sess_data->func = NULL; @@ -1657,9 +1666,9 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data) } #endif out: - kfree(ntlmssp_blob); + memzero_explicit(ntlmssp_blob, blob_length); SMB2_sess_free_buffer(sess_data); - kfree(ses->ntlmssp); + kfree_sensitive(ses->ntlmssp); ses->ntlmssp = NULL; sess_data->result = rc; sess_data->func = NULL; @@ -1737,7 +1746,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, cifs_server_dbg(VFS, "signing requested but authenticated as guest\n"); rc = sess_data->result; out: - kfree(sess_data); + kfree_sensitive(sess_data); return rc; } From 8698baa1b768fc5cd4bf73e846680a812678d029 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Wed, 5 Oct 2022 02:42:07 -0500 Subject: [PATCH 380/401] smb3: rename encryption/decryption TFMs Detach the TFM name from a specific algorithm (AES-CCM) as AES-GCM is also supported, making the name misleading. s/ccmaesencrypt/enc/ s/ccmaesdecrypt/dec/ Signed-off-by: Enzo Matsumiya Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/cifsencrypt.c | 12 ++++++------ fs/cifs/cifsglob.h | 4 ++-- fs/cifs/smb2ops.c | 3 +-- fs/cifs/smb2transport.c | 12 ++++++------ 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index d848bc0aac27..1f766f3e185e 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -743,14 +743,14 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server) server->secmech.hmacmd5 = NULL; } - if (server->secmech.ccmaesencrypt) { - crypto_free_aead(server->secmech.ccmaesencrypt); - server->secmech.ccmaesencrypt = NULL; + if (server->secmech.enc) { + crypto_free_aead(server->secmech.enc); + server->secmech.enc = NULL; } - if (server->secmech.ccmaesdecrypt) { - crypto_free_aead(server->secmech.ccmaesdecrypt); - server->secmech.ccmaesdecrypt = NULL; + if (server->secmech.dec) { + crypto_free_aead(server->secmech.dec); + server->secmech.dec = NULL; } kfree_sensitive(server->secmech.sdesccmacaes); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 338bc11f682e..95e90d662f06 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -171,8 +171,8 @@ struct cifs_secmech { struct sdesc *sdeschmacsha256; /* ctxt to generate smb2 signature */ struct sdesc *sdesccmacaes; /* ctxt to generate smb3 signature */ struct sdesc *sdescsha512; /* ctxt to generate smb3.11 signing key */ - struct crypto_aead *ccmaesencrypt; /* smb3 encryption aead */ - struct crypto_aead *ccmaesdecrypt; /* smb3 decryption aead */ + struct crypto_aead *enc; /* smb3 AEAD encryption TFM (AES-CCM and AES-GCM) */ + struct crypto_aead *dec; /* smb3 AEAD decryption TFM (AES-CCM and AES-GCM) */ }; /* per smb session structure/fields */ diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 9a686870e8b7..5187250c5f66 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4357,8 +4357,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, return rc; } - tfm = enc ? server->secmech.ccmaesencrypt : - server->secmech.ccmaesdecrypt; + tfm = enc ? server->secmech.enc : server->secmech.dec; if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index 4640fc4a8b13..d4e1a5d74dcd 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -904,7 +904,7 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server) { struct crypto_aead *tfm; - if (!server->secmech.ccmaesencrypt) { + if (!server->secmech.enc) { if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) || (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) tfm = crypto_alloc_aead("gcm(aes)", 0, 0); @@ -915,23 +915,23 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server) __func__); return PTR_ERR(tfm); } - server->secmech.ccmaesencrypt = tfm; + server->secmech.enc = tfm; } - if (!server->secmech.ccmaesdecrypt) { + if (!server->secmech.dec) { if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) || (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) tfm = crypto_alloc_aead("gcm(aes)", 0, 0); else tfm = crypto_alloc_aead("ccm(aes)", 0, 0); if (IS_ERR(tfm)) { - crypto_free_aead(server->secmech.ccmaesencrypt); - server->secmech.ccmaesencrypt = NULL; + crypto_free_aead(server->secmech.enc); + server->secmech.enc = NULL; cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n", __func__); return PTR_ERR(tfm); } - server->secmech.ccmaesdecrypt = tfm; + server->secmech.dec = tfm; } return 0; From 1f3d5477b944c8db8d73d7070ea98d8f1a8224c0 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Thu, 29 Sep 2022 17:36:50 -0300 Subject: [PATCH 381/401] cifs: secmech: use shash_desc directly, remove sdesc The struct sdesc is just a wrapper around shash_desc, with exact same memory layout. Replace the hashing TFMs with shash_desc as it's what's passed to the crypto API anyway. Also remove the crypto_shash pointers as they can be accessed via shash_desc->tfm (and are actually only used in the setkey calls). Adapt cifs_{alloc,free}_hash functions to this change. Signed-off-by: Enzo Matsumiya Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/cifsencrypt.c | 86 +++++++++++++---------------------------- fs/cifs/cifsglob.h | 26 ++++--------- fs/cifs/cifsproto.h | 5 +-- fs/cifs/link.c | 13 +++---- fs/cifs/misc.c | 49 ++++++++++++----------- fs/cifs/smb2misc.c | 13 +++---- fs/cifs/smb2transport.c | 72 +++++++++++++--------------------- 7 files changed, 98 insertions(+), 166 deletions(-) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 1f766f3e185e..5db73c0f792a 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -103,26 +103,24 @@ static int cifs_calc_signature(struct smb_rqst *rqst, if (!rqst->rq_iov || !signature || !server) return -EINVAL; - rc = cifs_alloc_hash("md5", &server->secmech.md5, - &server->secmech.sdescmd5); + rc = cifs_alloc_hash("md5", &server->secmech.md5); if (rc) return -1; - rc = crypto_shash_init(&server->secmech.sdescmd5->shash); + rc = crypto_shash_init(server->secmech.md5); if (rc) { cifs_dbg(VFS, "%s: Could not init md5\n", __func__); return rc; } - rc = crypto_shash_update(&server->secmech.sdescmd5->shash, + rc = crypto_shash_update(server->secmech.md5, server->session_key.response, server->session_key.len); if (rc) { cifs_dbg(VFS, "%s: Could not update with response\n", __func__); return rc; } - return __cifs_calc_signature(rqst, server, signature, - &server->secmech.sdescmd5->shash); + return __cifs_calc_signature(rqst, server, signature, server->secmech.md5); } /* must be called with server->srv_mutex held */ @@ -412,7 +410,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, wchar_t *domain; wchar_t *server; - if (!ses->server->secmech.sdeschmacmd5) { + if (!ses->server->secmech.hmacmd5) { cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__); return -1; } @@ -420,14 +418,14 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, /* calculate md4 hash of password */ E_md4hash(ses->password, nt_hash, nls_cp); - rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, + rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm, nt_hash, CIFS_NTHASH_SIZE); if (rc) { cifs_dbg(VFS, "%s: Could not set NT Hash as a key\n", __func__); return rc; } - rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); + rc = crypto_shash_init(ses->server->secmech.hmacmd5); if (rc) { cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); return rc; @@ -448,7 +446,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, memset(user, '\0', 2); } - rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + rc = crypto_shash_update(ses->server->secmech.hmacmd5, (char *)user, 2 * len); kfree(user); if (rc) { @@ -468,7 +466,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len, nls_cp); rc = - crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + crypto_shash_update(ses->server->secmech.hmacmd5, (char *)domain, 2 * len); kfree(domain); if (rc) { @@ -488,7 +486,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, len = cifs_strtoUTF16((__le16 *)server, ses->ip_addr, len, nls_cp); rc = - crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + crypto_shash_update(ses->server->secmech.hmacmd5, (char *)server, 2 * len); kfree(server); if (rc) { @@ -498,7 +496,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, } } - rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, + rc = crypto_shash_final(ses->server->secmech.hmacmd5, ntlmv2_hash); if (rc) cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); @@ -518,12 +516,12 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE + offsetof(struct ntlmv2_resp, challenge.key[0])); - if (!ses->server->secmech.sdeschmacmd5) { + if (!ses->server->secmech.hmacmd5) { cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__); return -1; } - rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, + rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); if (rc) { cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n", @@ -531,7 +529,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) return rc; } - rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); + rc = crypto_shash_init(ses->server->secmech.hmacmd5); if (rc) { cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); return rc; @@ -543,7 +541,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) else memcpy(ntlmv2->challenge.key, ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); - rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + rc = crypto_shash_update(ses->server->secmech.hmacmd5, ntlmv2->challenge.key, hash_len); if (rc) { cifs_dbg(VFS, "%s: Could not update with response\n", __func__); @@ -551,7 +549,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) } /* Note that the MD5 digest over writes anon.challenge_key.key */ - rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, + rc = crypto_shash_final(ses->server->secmech.hmacmd5, ntlmv2->ntlmv2_hash); if (rc) cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); @@ -627,9 +625,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) cifs_server_lock(ses->server); - rc = cifs_alloc_hash("hmac(md5)", - &ses->server->secmech.hmacmd5, - &ses->server->secmech.sdeschmacmd5); + rc = cifs_alloc_hash("hmac(md5)", &ses->server->secmech.hmacmd5); if (rc) { goto unlock; } @@ -649,7 +645,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) } /* now calculate the session key for NTLMv2 */ - rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, + rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); if (rc) { cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n", @@ -657,13 +653,13 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) goto unlock; } - rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); + rc = crypto_shash_init(ses->server->secmech.hmacmd5); if (rc) { cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); goto unlock; } - rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, + rc = crypto_shash_update(ses->server->secmech.hmacmd5, ntlmv2->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); if (rc) { @@ -671,7 +667,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) goto unlock; } - rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, + rc = crypto_shash_final(ses->server->secmech.hmacmd5, ses->auth_key.response); if (rc) cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); @@ -718,30 +714,11 @@ calc_seckey(struct cifs_ses *ses) void cifs_crypto_secmech_release(struct TCP_Server_Info *server) { - if (server->secmech.cmacaes) { - crypto_free_shash(server->secmech.cmacaes); - server->secmech.cmacaes = NULL; - } - - if (server->secmech.hmacsha256) { - crypto_free_shash(server->secmech.hmacsha256); - server->secmech.hmacsha256 = NULL; - } - - if (server->secmech.md5) { - crypto_free_shash(server->secmech.md5); - server->secmech.md5 = NULL; - } - - if (server->secmech.sha512) { - crypto_free_shash(server->secmech.sha512); - server->secmech.sha512 = NULL; - } - - if (server->secmech.hmacmd5) { - crypto_free_shash(server->secmech.hmacmd5); - server->secmech.hmacmd5 = NULL; - } + cifs_free_hash(&server->secmech.aes_cmac); + cifs_free_hash(&server->secmech.hmacsha256); + cifs_free_hash(&server->secmech.md5); + cifs_free_hash(&server->secmech.sha512); + cifs_free_hash(&server->secmech.hmacmd5); if (server->secmech.enc) { crypto_free_aead(server->secmech.enc); @@ -752,15 +729,4 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server) crypto_free_aead(server->secmech.dec); server->secmech.dec = NULL; } - - kfree_sensitive(server->secmech.sdesccmacaes); - server->secmech.sdesccmacaes = NULL; - kfree_sensitive(server->secmech.sdeschmacsha256); - server->secmech.sdeschmacsha256 = NULL; - kfree_sensitive(server->secmech.sdeschmacmd5); - server->secmech.sdeschmacmd5 = NULL; - kfree_sensitive(server->secmech.sdescmd5); - server->secmech.sdescmd5 = NULL; - kfree_sensitive(server->secmech.sdescsha512); - server->secmech.sdescsha512 = NULL; } diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 95e90d662f06..52ddf4163b98 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -153,26 +153,16 @@ struct session_key { char *response; }; -/* crypto security descriptor definition */ -struct sdesc { - struct shash_desc shash; - char ctx[]; -}; - /* crypto hashing related structure/fields, not specific to a sec mech */ struct cifs_secmech { - struct crypto_shash *hmacmd5; /* hmac-md5 hash function */ - struct crypto_shash *md5; /* md5 hash function */ - struct crypto_shash *hmacsha256; /* hmac-sha256 hash function */ - struct crypto_shash *cmacaes; /* block-cipher based MAC function */ - struct crypto_shash *sha512; /* sha512 hash function */ - struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */ - struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */ - struct sdesc *sdeschmacsha256; /* ctxt to generate smb2 signature */ - struct sdesc *sdesccmacaes; /* ctxt to generate smb3 signature */ - struct sdesc *sdescsha512; /* ctxt to generate smb3.11 signing key */ - struct crypto_aead *enc; /* smb3 AEAD encryption TFM (AES-CCM and AES-GCM) */ - struct crypto_aead *dec; /* smb3 AEAD decryption TFM (AES-CCM and AES-GCM) */ + struct shash_desc *hmacmd5; /* hmacmd5 hash function, for NTLMv2/CR1 hashes */ + struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */ + struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */ + struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */ + struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */ + + struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */ + struct crypto_aead *dec; /* smb3 decryption AEAD TFM (AES-CCM and AES-GCM) */ }; /* per smb session structure/fields */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 71386978858e..84ec71bdfacd 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -598,9 +598,8 @@ struct cifs_aio_ctx *cifs_aio_ctx_alloc(void); void cifs_aio_ctx_release(struct kref *refcount); int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw); -int cifs_alloc_hash(const char *name, struct crypto_shash **shash, - struct sdesc **sdesc); -void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc); +int cifs_alloc_hash(const char *name, struct shash_desc **sdesc); +void cifs_free_hash(struct shash_desc **sdesc); extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page, unsigned int *len, unsigned int *offset); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 6803cb27eecc..cd29c296cec6 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -38,29 +38,28 @@ static int symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) { int rc; - struct crypto_shash *md5 = NULL; - struct sdesc *sdescmd5 = NULL; + struct shash_desc *md5 = NULL; - rc = cifs_alloc_hash("md5", &md5, &sdescmd5); + rc = cifs_alloc_hash("md5", &md5); if (rc) goto symlink_hash_err; - rc = crypto_shash_init(&sdescmd5->shash); + rc = crypto_shash_init(md5); if (rc) { cifs_dbg(VFS, "%s: Could not init md5 shash\n", __func__); goto symlink_hash_err; } - rc = crypto_shash_update(&sdescmd5->shash, link_str, link_len); + rc = crypto_shash_update(md5, link_str, link_len); if (rc) { cifs_dbg(VFS, "%s: Could not update with link_str\n", __func__); goto symlink_hash_err; } - rc = crypto_shash_final(&sdescmd5->shash, md5_hash); + rc = crypto_shash_final(md5, md5_hash); if (rc) cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); symlink_hash_err: - cifs_free_hash(&md5, &sdescmd5); + cifs_free_hash(&md5); return rc; } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 72bd1b2b323f..da51ffd02928 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -1071,59 +1071,58 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw) /** * cifs_alloc_hash - allocate hash and hash context together * @name: The name of the crypto hash algo - * @shash: Where to put the pointer to the hash algo - * @sdesc: Where to put the pointer to the hash descriptor + * @sdesc: SHASH descriptor where to put the pointer to the hash TFM * * The caller has to make sure @sdesc is initialized to either NULL or - * a valid context. Both can be freed via cifs_free_hash(). + * a valid context. It can be freed via cifs_free_hash(). */ int -cifs_alloc_hash(const char *name, - struct crypto_shash **shash, struct sdesc **sdesc) +cifs_alloc_hash(const char *name, struct shash_desc **sdesc) { int rc = 0; - size_t size; + struct crypto_shash *alg = NULL; - if (*sdesc != NULL) + if (*sdesc) return 0; - *shash = crypto_alloc_shash(name, 0, 0); - if (IS_ERR(*shash)) { - cifs_dbg(VFS, "Could not allocate crypto %s\n", name); - rc = PTR_ERR(*shash); - *shash = NULL; + alg = crypto_alloc_shash(name, 0, 0); + if (IS_ERR(alg)) { + cifs_dbg(VFS, "Could not allocate shash TFM '%s'\n", name); + rc = PTR_ERR(alg); *sdesc = NULL; return rc; } - size = sizeof(struct shash_desc) + crypto_shash_descsize(*shash); - *sdesc = kmalloc(size, GFP_KERNEL); + *sdesc = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(alg), GFP_KERNEL); if (*sdesc == NULL) { - cifs_dbg(VFS, "no memory left to allocate crypto %s\n", name); - crypto_free_shash(*shash); - *shash = NULL; + cifs_dbg(VFS, "no memory left to allocate shash TFM '%s'\n", name); + crypto_free_shash(alg); return -ENOMEM; } - (*sdesc)->shash.tfm = *shash; + (*sdesc)->tfm = alg; return 0; } /** * cifs_free_hash - free hash and hash context together - * @shash: Where to find the pointer to the hash algo - * @sdesc: Where to find the pointer to the hash descriptor + * @sdesc: Where to find the pointer to the hash TFM * - * Freeing a NULL hash or context is safe. + * Freeing a NULL descriptor is safe. */ void -cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc) +cifs_free_hash(struct shash_desc **sdesc) { + if (unlikely(!sdesc) || !*sdesc) + return; + + if ((*sdesc)->tfm) { + crypto_free_shash((*sdesc)->tfm); + (*sdesc)->tfm = NULL; + } + kfree_sensitive(*sdesc); *sdesc = NULL; - if (*shash) - crypto_free_shash(*shash); - *shash = NULL; } /** diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index d73e5672aac4..7db5c09ecceb 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -870,8 +870,8 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server, struct kvec *iov, int nvec) { int i, rc; - struct sdesc *d; struct smb2_hdr *hdr; + struct shash_desc *sha512 = NULL; hdr = (struct smb2_hdr *)iov[0].iov_base; /* neg prot are always taken */ @@ -901,14 +901,14 @@ ok: if (rc) return rc; - d = server->secmech.sdescsha512; - rc = crypto_shash_init(&d->shash); + sha512 = server->secmech.sha512; + rc = crypto_shash_init(sha512); if (rc) { cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__); return rc; } - rc = crypto_shash_update(&d->shash, ses->preauth_sha_hash, + rc = crypto_shash_update(sha512, ses->preauth_sha_hash, SMB2_PREAUTH_HASH_SIZE); if (rc) { cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); @@ -916,8 +916,7 @@ ok: } for (i = 0; i < nvec; i++) { - rc = crypto_shash_update(&d->shash, - iov[i].iov_base, iov[i].iov_len); + rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len); if (rc) { cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); @@ -925,7 +924,7 @@ ok: } } - rc = crypto_shash_final(&d->shash, ses->preauth_sha_hash); + rc = crypto_shash_final(sha512, ses->preauth_sha_hash); if (rc) { cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n", __func__); diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index d4e1a5d74dcd..dfcbcc0b86e4 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -32,19 +32,17 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server) struct cifs_secmech *p = &server->secmech; int rc; - rc = cifs_alloc_hash("hmac(sha256)", - &p->hmacsha256, - &p->sdeschmacsha256); + rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256); if (rc) goto err; - rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes); + rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac); if (rc) goto err; return 0; err: - cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256); + cifs_free_hash(&p->hmacsha256); return rc; } @@ -54,25 +52,23 @@ smb311_crypto_shash_allocate(struct TCP_Server_Info *server) struct cifs_secmech *p = &server->secmech; int rc = 0; - rc = cifs_alloc_hash("hmac(sha256)", - &p->hmacsha256, - &p->sdeschmacsha256); + rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256); if (rc) return rc; - rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes); + rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac); if (rc) goto err; - rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512); + rc = cifs_alloc_hash("sha512", &p->sha512); if (rc) goto err; return 0; err: - cifs_free_hash(&p->cmacaes, &p->sdesccmacaes); - cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256); + cifs_free_hash(&p->aes_cmac); + cifs_free_hash(&p->hmacsha256); return rc; } @@ -220,8 +216,6 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base; struct cifs_ses *ses; struct shash_desc *shash; - struct crypto_shash *hash; - struct sdesc *sdesc = NULL; struct smb_rqst drqst; ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId)); @@ -234,19 +228,17 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE); if (allocate_crypto) { - rc = cifs_alloc_hash("hmac(sha256)", &hash, &sdesc); + rc = cifs_alloc_hash("hmac(sha256)", &shash); if (rc) { cifs_server_dbg(VFS, "%s: sha256 alloc failed\n", __func__); goto out; } - shash = &sdesc->shash; } else { - hash = server->secmech.hmacsha256; - shash = &server->secmech.sdeschmacsha256->shash; + shash = server->secmech.hmacsha256; } - rc = crypto_shash_setkey(hash, ses->auth_key.response, + rc = crypto_shash_setkey(shash->tfm, ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); if (rc) { cifs_server_dbg(VFS, @@ -288,7 +280,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, out: if (allocate_crypto) - cifs_free_hash(&hash, &sdesc); + cifs_free_hash(&shash); if (ses) cifs_put_smb_ses(ses); return rc; @@ -315,42 +307,38 @@ static int generate_key(struct cifs_ses *ses, struct kvec label, goto smb3signkey_ret; } - rc = crypto_shash_setkey(server->secmech.hmacsha256, + rc = crypto_shash_setkey(server->secmech.hmacsha256->tfm, ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); if (rc) { cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__); goto smb3signkey_ret; } - rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash); + rc = crypto_shash_init(server->secmech.hmacsha256); if (rc) { cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__); goto smb3signkey_ret; } - rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, - i, 4); + rc = crypto_shash_update(server->secmech.hmacsha256, i, 4); if (rc) { cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__); goto smb3signkey_ret; } - rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, - label.iov_base, label.iov_len); + rc = crypto_shash_update(server->secmech.hmacsha256, label.iov_base, label.iov_len); if (rc) { cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__); goto smb3signkey_ret; } - rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, - &zero, 1); + rc = crypto_shash_update(server->secmech.hmacsha256, &zero, 1); if (rc) { cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__); goto smb3signkey_ret; } - rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, - context.iov_base, context.iov_len); + rc = crypto_shash_update(server->secmech.hmacsha256, context.iov_base, context.iov_len); if (rc) { cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__); goto smb3signkey_ret; @@ -358,19 +346,16 @@ static int generate_key(struct cifs_ses *ses, struct kvec label, if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) { - rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, - L256, 4); + rc = crypto_shash_update(server->secmech.hmacsha256, L256, 4); } else { - rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, - L128, 4); + rc = crypto_shash_update(server->secmech.hmacsha256, L128, 4); } if (rc) { cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__); goto smb3signkey_ret; } - rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash, - hashptr); + rc = crypto_shash_final(server->secmech.hmacsha256, hashptr); if (rc) { cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__); goto smb3signkey_ret; @@ -551,8 +536,6 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, struct kvec *iov = rqst->rq_iov; struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base; struct shash_desc *shash; - struct crypto_shash *hash; - struct sdesc *sdesc = NULL; struct smb_rqst drqst; u8 key[SMB3_SIGN_KEY_SIZE]; @@ -563,27 +546,24 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, } if (allocate_crypto) { - rc = cifs_alloc_hash("cmac(aes)", &hash, &sdesc); + rc = cifs_alloc_hash("cmac(aes)", &shash); if (rc) return rc; - - shash = &sdesc->shash; } else { - hash = server->secmech.cmacaes; - shash = &server->secmech.sdesccmacaes->shash; + shash = server->secmech.aes_cmac; } memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE); memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE); - rc = crypto_shash_setkey(hash, key, SMB2_CMACAES_SIZE); + rc = crypto_shash_setkey(shash->tfm, key, SMB2_CMACAES_SIZE); if (rc) { cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__); goto out; } /* - * we already allocate sdesccmacaes when we init smb3 signing key, + * we already allocate aes_cmac when we init smb3 signing key, * so unlike smb2 case we do not have to check here if secmech are * initialized */ @@ -619,7 +599,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, out: if (allocate_crypto) - cifs_free_hash(&hash, &sdesc); + cifs_free_hash(&shash); return rc; } From 958553d13478ad0e35fa09fecad3ce73277ccaf5 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 2 Oct 2022 22:09:45 -0500 Subject: [PATCH 382/401] smb3: fix oops in calculating shash_setkey shash was not being initialized in one place in smb3_calc_signature and smb2_calc_signature Reviewed-by: Enzo Matsumiya Acked-by: Tom Talpey Signed-off-by: Steve French --- fs/cifs/smb2transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index dfcbcc0b86e4..8e3f26e6f6b9 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -215,7 +215,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, struct kvec *iov = rqst->rq_iov; struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base; struct cifs_ses *ses; - struct shash_desc *shash; + struct shash_desc *shash = NULL; struct smb_rqst drqst; ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId)); @@ -535,7 +535,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, unsigned char *sigptr = smb3_signature; struct kvec *iov = rqst->rq_iov; struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base; - struct shash_desc *shash; + struct shash_desc *shash = NULL; struct smb_rqst drqst; u8 key[SMB3_SIGN_KEY_SIZE]; From 59945216889518982d262d4cab099c6554f58867 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 7 Sep 2022 14:50:56 +0100 Subject: [PATCH 383/401] fbdev: udlfb: Remove redundant initialization to variable identical The variable identical is being initialized with a value that is never read. The variable is being re-assigned later on. The initialization is redundant and can be removed. Cleans up clang scan-build warning: drivers/video/fbdev/udlfb.c:373:6: warning: Value stored to 'identical' during its initialization is never read [deadcode.DeadStores] Signed-off-by: Colin Ian King Signed-off-by: Helge Deller --- drivers/video/fbdev/udlfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index c863244ef12c..216d49c9d47e 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -370,7 +370,7 @@ static int dlfb_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes) const unsigned long *back = (const unsigned long *) bback; const unsigned long *front = (const unsigned long *) *bfront; const int width = *width_bytes / sizeof(unsigned long); - int identical = width; + int identical; int start = width; int end = width; From 83434cc0ae8c344b085d0ed6104e3b91e5f02a09 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 14 Sep 2022 18:22:59 +0800 Subject: [PATCH 384/401] fbdev: controlfb: Remove the unused function VAR_MATCH() The function VAR_MATCH is defined in the controlfb.c file, but not called elsewhere, so delete this unused function. drivers/video/fbdev/controlfb.c:111:19: warning: unused function 'VAR_MATCH'. Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=2153 Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Helge Deller --- drivers/video/fbdev/controlfb.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c index aba46118b208..6bbcd9fc864e 100644 --- a/drivers/video/fbdev/controlfb.c +++ b/drivers/video/fbdev/controlfb.c @@ -108,13 +108,6 @@ static inline int PAR_EQUAL(struct fb_par_control *x, struct fb_par_control *y) return (!DIRTY(cmode) && !DIRTY(xres) && !DIRTY(yres) && !DIRTY(vxres) && !DIRTY(vyres)); } -static inline int VAR_MATCH(struct fb_var_screeninfo *x, struct fb_var_screeninfo *y) -{ - return (!DIRTY(bits_per_pixel) && !DIRTY(xres) - && !DIRTY(yres) && !DIRTY(xres_virtual) - && !DIRTY(yres_virtual) - && !DIRTY_CMAP(red) && !DIRTY_CMAP(green) && !DIRTY_CMAP(blue)); -} struct fb_info_control { struct fb_info info; From eec5190fc0b14130ed2f67b0de43b6a302b7837f Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 14 Sep 2022 18:23:00 +0800 Subject: [PATCH 385/401] fbdev: tridentfb: Remove the unused function shadowmode_off() The function shadowmode_off() is defined in the tridentfb.c file, but not called elsewhere, so delete this unused function. drivers/video/fbdev/tridentfb.c:1131:20: warning: unused function 'shadowmode_off'. Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=2154 Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Helge Deller --- drivers/video/fbdev/tridentfb.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c index f9c3b1d38fc2..2154dd5e37bd 100644 --- a/drivers/video/fbdev/tridentfb.c +++ b/drivers/video/fbdev/tridentfb.c @@ -1128,11 +1128,6 @@ static inline void shadowmode_on(struct tridentfb_par *par) write3CE(par, CyberControl, read3CE(par, CyberControl) | 0x81); } -static inline void shadowmode_off(struct tridentfb_par *par) -{ - write3CE(par, CyberControl, read3CE(par, CyberControl) & 0x7E); -} - /* Set the hardware to the requested video mode */ static int tridentfb_set_par(struct fb_info *info) { From 851e0986d964bb75deea24011b0845d550215076 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 14 Sep 2022 18:23:01 +0800 Subject: [PATCH 386/401] fbdev: arkfb: Remove the unused function dac_read_reg() The function dac_read_reg() is defined in the arkfb.c file, but not called elsewhere, so delete this unused function. drivers/video/fbdev/arkfb.c:322:18: warning: unused function 'dac_read_reg'. Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=2155 Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Helge Deller --- drivers/video/fbdev/arkfb.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c index a317d9fe1d67..5f8fec9e5fd4 100644 --- a/drivers/video/fbdev/arkfb.c +++ b/drivers/video/fbdev/arkfb.c @@ -318,14 +318,6 @@ struct dac_info void *data; }; - -static inline u8 dac_read_reg(struct dac_info *info, u8 reg) -{ - u8 code[2] = {reg, 0}; - info->dac_read_regs(info->data, code, 1); - return code[1]; -} - static inline void dac_read_regs(struct dac_info *info, u8 *code, int count) { info->dac_read_regs(info->data, code, count); From 2559f17ec878adf5c54815e55cf0b72c02bb5303 Mon Sep 17 00:00:00 2001 From: Jules Irenge Date: Sun, 18 Sep 2022 00:44:20 +0100 Subject: [PATCH 387/401] fbdev: uvesafb: Convert snprintf to scnprintf Coccinelle reports: WARNING: use scnprintf or sprintf Adding to that, there has also been some slow migration from snprintf to scnprintf. This article explains the rationale for this change: https: //lwn.net/Articles/69419/ Signed-off-by: Jules Irenge Signed-off-by: Helge Deller --- drivers/video/fbdev/uvesafb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c index 4df6772802d7..fd5d701106e1 100644 --- a/drivers/video/fbdev/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -1580,7 +1580,7 @@ static ssize_t uvesafb_show_vendor(struct device *dev, struct uvesafb_par *par = info->par; if (par->vbe_ib.oem_vendor_name_ptr) - return snprintf(buf, PAGE_SIZE, "%s\n", (char *) + return scnprintf(buf, PAGE_SIZE, "%s\n", (char *) (&par->vbe_ib) + par->vbe_ib.oem_vendor_name_ptr); else return 0; @@ -1595,7 +1595,7 @@ static ssize_t uvesafb_show_product_name(struct device *dev, struct uvesafb_par *par = info->par; if (par->vbe_ib.oem_product_name_ptr) - return snprintf(buf, PAGE_SIZE, "%s\n", (char *) + return scnprintf(buf, PAGE_SIZE, "%s\n", (char *) (&par->vbe_ib) + par->vbe_ib.oem_product_name_ptr); else return 0; @@ -1610,7 +1610,7 @@ static ssize_t uvesafb_show_product_rev(struct device *dev, struct uvesafb_par *par = info->par; if (par->vbe_ib.oem_product_rev_ptr) - return snprintf(buf, PAGE_SIZE, "%s\n", (char *) + return scnprintf(buf, PAGE_SIZE, "%s\n", (char *) (&par->vbe_ib) + par->vbe_ib.oem_product_rev_ptr); else return 0; @@ -1625,7 +1625,7 @@ static ssize_t uvesafb_show_oem_string(struct device *dev, struct uvesafb_par *par = info->par; if (par->vbe_ib.oem_string_ptr) - return snprintf(buf, PAGE_SIZE, "%s\n", + return scnprintf(buf, PAGE_SIZE, "%s\n", (char *)(&par->vbe_ib) + par->vbe_ib.oem_string_ptr); else return 0; @@ -1639,7 +1639,7 @@ static ssize_t uvesafb_show_nocrtc(struct device *dev, struct fb_info *info = dev_get_drvdata(dev); struct uvesafb_par *par = info->par; - return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc); + return scnprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc); } static ssize_t uvesafb_store_nocrtc(struct device *dev, From b0e0706007030d1eb05d25de0359725357fe5be6 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Fri, 23 Sep 2022 21:38:44 +0800 Subject: [PATCH 388/401] fbdev: omapfb/dss: Use pm_runtime_resume_and_get() instead of pm_runtime_get_sync() Using the newest pm_runtime_resume_and_get is more appropriate for simplifing code here. Signed-off-by: Zhang Qilong Signed-off-by: Helge Deller --- drivers/video/fbdev/omap2/omapfb/dss/dispc.c | 6 ++---- drivers/video/fbdev/omap2/omapfb/dss/dsi.c | 6 ++---- drivers/video/fbdev/omap2/omapfb/dss/dss.c | 6 ++---- drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c | 6 ++---- drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c | 6 ++---- drivers/video/fbdev/omap2/omapfb/dss/venc.c | 6 ++---- 6 files changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dispc.c b/drivers/video/fbdev/omap2/omapfb/dss/dispc.c index b2d6e6df2161..92fb6b7e1f68 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dispc.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dispc.c @@ -519,11 +519,9 @@ int dispc_runtime_get(void) DSSDBG("dispc_runtime_get\n"); - r = pm_runtime_get_sync(&dispc.pdev->dev); - if (WARN_ON(r < 0)) { - pm_runtime_put_sync(&dispc.pdev->dev); + r = pm_runtime_resume_and_get(&dispc.pdev->dev); + if (WARN_ON(r < 0)) return r; - } return 0; } EXPORT_SYMBOL(dispc_runtime_get); diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c index d43b081d592f..54b0f034c2ed 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c @@ -1136,11 +1136,9 @@ static int dsi_runtime_get(struct platform_device *dsidev) DSSDBG("dsi_runtime_get\n"); - r = pm_runtime_get_sync(&dsi->pdev->dev); - if (WARN_ON(r < 0)) { - pm_runtime_put_sync(&dsi->pdev->dev); + r = pm_runtime_resume_and_get(&dsi->pdev->dev); + if (WARN_ON(r < 0)) return r; - } return 0; } diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.c b/drivers/video/fbdev/omap2/omapfb/dss/dss.c index 45b9d3cf3860..335e0af4eec1 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dss.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.c @@ -767,11 +767,9 @@ int dss_runtime_get(void) DSSDBG("dss_runtime_get\n"); - r = pm_runtime_get_sync(&dss.pdev->dev); - if (WARN_ON(r < 0)) { - pm_runtime_put_sync(&dss.pdev->dev); + r = pm_runtime_resume_and_get(&dss.pdev->dev); + if (WARN_ON(r < 0)) return r; - } return 0; } diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c index 800bd108e834..0f39612e002e 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c @@ -38,11 +38,9 @@ static int hdmi_runtime_get(void) DSSDBG("hdmi_runtime_get\n"); - r = pm_runtime_get_sync(&hdmi.pdev->dev); - if (WARN_ON(r < 0)) { - pm_runtime_put_sync(&hdmi.pdev->dev); + r = pm_runtime_resume_and_get(&hdmi.pdev->dev); + if (WARN_ON(r < 0)) return r; - } return 0; } diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c index 2c03608addcd..bfccc2cb917a 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c @@ -42,11 +42,9 @@ static int hdmi_runtime_get(void) DSSDBG("hdmi_runtime_get\n"); - r = pm_runtime_get_sync(&hdmi.pdev->dev); - if (WARN_ON(r < 0)) { - pm_runtime_put_sync(&hdmi.pdev->dev); + r = pm_runtime_resume_and_get(&hdmi.pdev->dev); + if (WARN_ON(r < 0)) return r; - } return 0; } diff --git a/drivers/video/fbdev/omap2/omapfb/dss/venc.c b/drivers/video/fbdev/omap2/omapfb/dss/venc.c index 905d642ff9ed..78a7309d25dd 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/venc.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/venc.c @@ -347,11 +347,9 @@ static int venc_runtime_get(void) DSSDBG("venc_runtime_get\n"); - r = pm_runtime_get_sync(&venc.pdev->dev); - if (WARN_ON(r < 0)) { - pm_runtime_put_sync(&venc.pdev->dev); + r = pm_runtime_resume_and_get(&venc.pdev->dev); + if (WARN_ON(r < 0)) return r; - } return 0; } From d13189badcb2d850244034eb73faeb61edce914e Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Fri, 23 Sep 2022 18:20:07 +0800 Subject: [PATCH 389/401] fbdev: imxfb: Remove redundant dev_err() call devm_ioremap_resource() prints error message in itself. Remove the dev_err call to avoid redundant error message. Signed-off-by: Shang XiaoJing Signed-off-by: Helge Deller --- drivers/video/fbdev/imxfb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index 94f3bc637fc8..51fde1b2a793 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -972,7 +972,6 @@ static int imxfb_probe(struct platform_device *pdev) fbi->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(fbi->regs)) { - dev_err(&pdev->dev, "Cannot map frame buffer registers\n"); ret = PTR_ERR(fbi->regs); goto failed_ioremap; } From e69dade8a4cfe49f3f3af90d966dd34b67721d26 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Fri, 2 Sep 2022 10:55:55 +0800 Subject: [PATCH 390/401] fbdev: gbefb: Convert to use dev_groups The driver core supports the ability to handle the creation and removal of device-specific sysfs files in a race-free manner. Moreover, it can guarantee the success of creation. Therefore, it should be better to convert to use dev_groups. Signed-off-by: Jiasheng Jiang Signed-off-by: Helge Deller --- drivers/video/fbdev/gbefb.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c index 6b4d5a7f3e15..1582c718329c 100644 --- a/drivers/video/fbdev/gbefb.c +++ b/drivers/video/fbdev/gbefb.c @@ -1072,17 +1072,12 @@ static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *at static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL); -static void gbefb_remove_sysfs(struct device *dev) -{ - device_remove_file(dev, &dev_attr_size); - device_remove_file(dev, &dev_attr_revision); -} - -static void gbefb_create_sysfs(struct device *dev) -{ - device_create_file(dev, &dev_attr_size); - device_create_file(dev, &dev_attr_revision); -} +static struct attribute *gbefb_attrs[] = { + &dev_attr_size.attr, + &dev_attr_revision.attr, + NULL, +}; +ATTRIBUTE_GROUPS(gbefb); /* * Initialization @@ -1221,7 +1216,6 @@ static int gbefb_probe(struct platform_device *p_dev) } platform_set_drvdata(p_dev, info); - gbefb_create_sysfs(&p_dev->dev); fb_info(info, "%s rev %d @ 0x%08x using %dkB memory\n", info->fix.id, gbe_revision, (unsigned)GBE_BASE, @@ -1248,7 +1242,6 @@ static int gbefb_remove(struct platform_device* p_dev) gbe_turn_off(); arch_phys_wc_del(par->wc_cookie); release_mem_region(GBE_BASE, sizeof(struct sgi_gbe)); - gbefb_remove_sysfs(&p_dev->dev); framebuffer_release(info); return 0; @@ -1259,6 +1252,7 @@ static struct platform_driver gbefb_driver = { .remove = gbefb_remove, .driver = { .name = "gbefb", + .dev_groups = gbefb_groups, }, }; From 5610bcfe8693c02e2e4c8b31427f1bdbdecc839c Mon Sep 17 00:00:00 2001 From: Hyunwoo Kim Date: Sun, 25 Sep 2022 06:32:43 -0700 Subject: [PATCH 391/401] fbdev: smscufx: Fix use-after-free in ufx_ops_open() A race condition may occur if the user physically removes the USB device while calling open() for this device node. This is a race condition between the ufx_ops_open() function and the ufx_usb_disconnect() function, which may eventually result in UAF. So, add a mutex to the ufx_ops_open() and ufx_usb_disconnect() functions to avoid race contidion of krefs. Signed-off-by: Hyunwoo Kim Cc: stable@vger.kernel.org Signed-off-by: Helge Deller --- drivers/video/fbdev/smscufx.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c index d7aa5511c361..e65bdc499c23 100644 --- a/drivers/video/fbdev/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -137,6 +137,8 @@ static int ufx_submit_urb(struct ufx_data *dev, struct urb * urb, size_t len); static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size); static void ufx_free_urb_list(struct ufx_data *dev); +static DEFINE_MUTEX(disconnect_mutex); + /* reads a control register */ static int ufx_reg_read(struct ufx_data *dev, u32 index, u32 *data) { @@ -1071,9 +1073,13 @@ static int ufx_ops_open(struct fb_info *info, int user) if (user == 0 && !console) return -EBUSY; + mutex_lock(&disconnect_mutex); + /* If the USB device is gone, we don't accept new opens */ - if (dev->virtualized) + if (dev->virtualized) { + mutex_unlock(&disconnect_mutex); return -ENODEV; + } dev->fb_count++; @@ -1097,6 +1103,8 @@ static int ufx_ops_open(struct fb_info *info, int user) pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d", info->node, user, info, dev->fb_count); + mutex_unlock(&disconnect_mutex); + return 0; } @@ -1741,6 +1749,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface) { struct ufx_data *dev; + mutex_lock(&disconnect_mutex); + dev = usb_get_intfdata(interface); pr_debug("USB disconnect starting\n"); @@ -1761,6 +1771,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface) kref_put(&dev->kref, ufx_free); /* consider ufx_data freed */ + + mutex_unlock(&disconnect_mutex); } static struct usb_driver ufx_driver = { From e82b0c3ea520609b953ace13ae8d44ba7b3cee54 Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Thu, 22 Sep 2022 09:37:09 +0800 Subject: [PATCH 392/401] fbdev: tridentfb: Fix missing pci_disable_device() in probe and remove Replace pci_enable_device() with pcim_enable_device(), pci_disable_device() and pci_release_regions() will be called in release automatically. Signed-off-by: ruanjinjie Signed-off-by: Helge Deller --- drivers/video/fbdev/tridentfb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c index 2154dd5e37bd..219ce7292337 100644 --- a/drivers/video/fbdev/tridentfb.c +++ b/drivers/video/fbdev/tridentfb.c @@ -1470,7 +1470,7 @@ static int trident_pci_probe(struct pci_dev *dev, if (err) return err; - err = pci_enable_device(dev); + err = pcim_enable_device(dev); if (err) return err; @@ -1710,12 +1710,10 @@ out_unmap2: kfree(info->pixmap.addr); if (info->screen_base) iounmap(info->screen_base); - release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); disable_mmio(info->par); out_unmap1: if (default_par->io_virt) iounmap(default_par->io_virt); - release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); framebuffer_release(info); return err; } @@ -1730,8 +1728,6 @@ static void trident_pci_remove(struct pci_dev *dev) i2c_del_adapter(&par->ddc_adapter); iounmap(par->io_virt); iounmap(info->screen_base); - release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); - release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); kfree(info->pixmap.addr); fb_dealloc_cmap(&info->cmap); framebuffer_release(info); From 3b29f36efc2fc0d09a178d6d4f9e772f3ffe8591 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Wed, 28 Sep 2022 23:17:10 +0800 Subject: [PATCH 393/401] fbdev: vga16fb: Add missing MODULE_DEVICE_TABLE() entry This patch adds missing MODULE_DEVICE_TABLE definition which generates correct modalias for automatic loading of this driver when it is built as an external module. Signed-off-by: Zeng Heng Signed-off-by: Helge Deller --- drivers/video/fbdev/vga16fb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index 35cf51ae3292..af47f8217095 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -1421,6 +1421,7 @@ static const struct platform_device_id vga16fb_driver_id_table[] = { {"vga-framebuffer", 0}, { } }; +MODULE_DEVICE_TABLE(platform, vga16fb_driver_id_table); static struct platform_driver vga16fb_driver = { .probe = vga16fb_probe, From 29926f1cd3535f565f200430d5b6a794543fe130 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 6 Oct 2022 07:33:17 +0200 Subject: [PATCH 394/401] fbdev: mb862xx: Fix check of return value from irq_of_parse_and_map() NO_IRQ is used to check the return of irq_of_parse_and_map(). On some architecture NO_IRQ is 0, on other architectures it is -1. irq_of_parse_and_map() returns 0 on error, independent of NO_IRQ. So use 0 instead of using NO_IRQ. Signed-off-by: Christophe Leroy Signed-off-by: Helge Deller --- drivers/video/fbdev/mb862xx/mb862xxfbdrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c index 96800c9c9cd9..90c79e8c1157 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c @@ -693,7 +693,7 @@ static int of_platform_mb862xx_probe(struct platform_device *ofdev) par->dev = dev; par->irq = irq_of_parse_and_map(np, 0); - if (par->irq == NO_IRQ) { + if (!par->irq) { dev_err(dev, "failed to map irq\n"); ret = -ENODEV; goto fbrel; From 17406967ec0ff8e14737ee7a073c7a45fc8210f1 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 30 Sep 2022 22:53:06 -0700 Subject: [PATCH 395/401] Input: pinephone-keyboard - add PinePhone keyboard driver The official Pine64 PinePhone keyboard case contains a matrix keypad and a MCU which runs a libre firmware. Add support for its I2C interface. Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20220618165747.55709-3-samuel@sholland.org Signed-off-by: Dmitry Torokhov --- MAINTAINERS | 6 + drivers/input/keyboard/Kconfig | 13 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/pinephone-keyboard.c | 392 ++++++++++++++++++++ 4 files changed, 412 insertions(+) create mode 100644 drivers/input/keyboard/pinephone-keyboard.c diff --git a/MAINTAINERS b/MAINTAINERS index aa71df8b699b..9ddcc242081c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16186,6 +16186,12 @@ F: Documentation/devicetree/bindings/pinctrl/sunplus,* F: drivers/pinctrl/sunplus/ F: include/dt-bindings/pinctrl/sppctl*.h +PINE64 PINEPHONE KEYBOARD DRIVER +M: Samuel Holland +S: Supported +F: Documentation/devicetree/bindings/input/pine64,pinephone-keyboard.yaml +F: drivers/input/keyboard/pinephone-keyboard.c + PKTCDVD DRIVER M: linux-block@vger.kernel.org S: Orphan diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 8b0281c4f3c5..00292118b79b 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -527,6 +527,19 @@ config KEYBOARD_OPENCORES To compile this driver as a module, choose M here; the module will be called opencores-kbd. +config KEYBOARD_PINEPHONE + tristate "Pine64 PinePhone Keyboard" + depends on I2C && REGULATOR + select CRC8 + select INPUT_MATRIXKMAP + help + Say Y here to enable support for the keyboard in the Pine64 PinePhone + keyboard case. This driver supports the FLOSS firmware available at + https://megous.com/git/pinephone-keyboard/ + + To compile this driver as a module, choose M here; the + module will be called pinephone-keyboard. + config KEYBOARD_PXA27x tristate "PXA27x/PXA3xx keypad support" depends on PXA27x || PXA3xx || ARCH_MMP diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 721936e90290..5f67196bb2c1 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_KEYBOARD_NSPIRE) += nspire-keypad.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o obj-$(CONFIG_KEYBOARD_OMAP4) += omap4-keypad.o obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o +obj-$(CONFIG_KEYBOARD_PINEPHONE) += pinephone-keyboard.o obj-$(CONFIG_KEYBOARD_PMIC8XXX) += pmic8xxx-keypad.o obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o diff --git a/drivers/input/keyboard/pinephone-keyboard.c b/drivers/input/keyboard/pinephone-keyboard.c new file mode 100644 index 000000000000..b10113b4b29b --- /dev/null +++ b/drivers/input/keyboard/pinephone-keyboard.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (C) 2021-2022 Samuel Holland + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "pinephone-keyboard" + +#define PPKB_CRC8_POLYNOMIAL 0x07 + +#define PPKB_DEVICE_ID_HI 0x00 +#define PPKB_DEVICE_ID_HI_VALUE 'K' +#define PPKB_DEVICE_ID_LO 0x01 +#define PPKB_DEVICE_ID_LO_VALUE 'B' +#define PPKB_FW_REVISION 0x02 +#define PPKB_FW_FEATURES 0x03 +#define PPKB_MATRIX_SIZE 0x06 +#define PPKB_SCAN_CRC 0x07 +#define PPKB_SCAN_DATA 0x08 +#define PPKB_SYS_CONFIG 0x20 +#define PPKB_SYS_CONFIG_DISABLE_SCAN BIT(0) + +#define PPKB_ROWS 6 +#define PPKB_COLS 12 + +/* Size of the scan buffer, including the CRC byte at the beginning. */ +#define PPKB_BUF_LEN (1 + PPKB_COLS) + +static const uint32_t ppkb_keymap[] = { + KEY(0, 0, KEY_ESC), + KEY(0, 1, KEY_1), + KEY(0, 2, KEY_2), + KEY(0, 3, KEY_3), + KEY(0, 4, KEY_4), + KEY(0, 5, KEY_5), + KEY(0, 6, KEY_6), + KEY(0, 7, KEY_7), + KEY(0, 8, KEY_8), + KEY(0, 9, KEY_9), + KEY(0, 10, KEY_0), + KEY(0, 11, KEY_BACKSPACE), + + KEY(1, 0, KEY_TAB), + KEY(1, 1, KEY_Q), + KEY(1, 2, KEY_W), + KEY(1, 3, KEY_E), + KEY(1, 4, KEY_R), + KEY(1, 5, KEY_T), + KEY(1, 6, KEY_Y), + KEY(1, 7, KEY_U), + KEY(1, 8, KEY_I), + KEY(1, 9, KEY_O), + KEY(1, 10, KEY_P), + KEY(1, 11, KEY_ENTER), + + KEY(2, 0, KEY_LEFTMETA), + KEY(2, 1, KEY_A), + KEY(2, 2, KEY_S), + KEY(2, 3, KEY_D), + KEY(2, 4, KEY_F), + KEY(2, 5, KEY_G), + KEY(2, 6, KEY_H), + KEY(2, 7, KEY_J), + KEY(2, 8, KEY_K), + KEY(2, 9, KEY_L), + KEY(2, 10, KEY_SEMICOLON), + + KEY(3, 0, KEY_LEFTSHIFT), + KEY(3, 1, KEY_Z), + KEY(3, 2, KEY_X), + KEY(3, 3, KEY_C), + KEY(3, 4, KEY_V), + KEY(3, 5, KEY_B), + KEY(3, 6, KEY_N), + KEY(3, 7, KEY_M), + KEY(3, 8, KEY_COMMA), + KEY(3, 9, KEY_DOT), + KEY(3, 10, KEY_SLASH), + + KEY(4, 1, KEY_LEFTCTRL), + KEY(4, 4, KEY_SPACE), + KEY(4, 6, KEY_APOSTROPHE), + KEY(4, 8, KEY_RIGHTBRACE), + KEY(4, 9, KEY_LEFTBRACE), + + KEY(5, 2, KEY_FN), + KEY(5, 3, KEY_LEFTALT), + KEY(5, 5, KEY_RIGHTALT), + + /* FN layer */ + KEY(PPKB_ROWS + 0, 0, KEY_FN_ESC), + KEY(PPKB_ROWS + 0, 1, KEY_F1), + KEY(PPKB_ROWS + 0, 2, KEY_F2), + KEY(PPKB_ROWS + 0, 3, KEY_F3), + KEY(PPKB_ROWS + 0, 4, KEY_F4), + KEY(PPKB_ROWS + 0, 5, KEY_F5), + KEY(PPKB_ROWS + 0, 6, KEY_F6), + KEY(PPKB_ROWS + 0, 7, KEY_F7), + KEY(PPKB_ROWS + 0, 8, KEY_F8), + KEY(PPKB_ROWS + 0, 9, KEY_F9), + KEY(PPKB_ROWS + 0, 10, KEY_F10), + KEY(PPKB_ROWS + 0, 11, KEY_DELETE), + + KEY(PPKB_ROWS + 1, 10, KEY_PAGEUP), + + KEY(PPKB_ROWS + 2, 0, KEY_SYSRQ), + KEY(PPKB_ROWS + 2, 9, KEY_PAGEDOWN), + KEY(PPKB_ROWS + 2, 10, KEY_INSERT), + + KEY(PPKB_ROWS + 3, 0, KEY_LEFTSHIFT), + KEY(PPKB_ROWS + 3, 8, KEY_HOME), + KEY(PPKB_ROWS + 3, 9, KEY_UP), + KEY(PPKB_ROWS + 3, 10, KEY_END), + + KEY(PPKB_ROWS + 4, 1, KEY_LEFTCTRL), + KEY(PPKB_ROWS + 4, 6, KEY_LEFT), + KEY(PPKB_ROWS + 4, 8, KEY_RIGHT), + KEY(PPKB_ROWS + 4, 9, KEY_DOWN), + + KEY(PPKB_ROWS + 5, 3, KEY_LEFTALT), + KEY(PPKB_ROWS + 5, 5, KEY_RIGHTALT), +}; + +static const struct matrix_keymap_data ppkb_keymap_data = { + .keymap = ppkb_keymap, + .keymap_size = ARRAY_SIZE(ppkb_keymap), +}; + +struct pinephone_keyboard { + struct input_dev *input; + u8 buf[2][PPKB_BUF_LEN]; + u8 crc_table[CRC8_TABLE_SIZE]; + u8 fn_state[PPKB_COLS]; + bool buf_swap; + bool fn_pressed; +}; + +static void ppkb_update(struct i2c_client *client) +{ + struct pinephone_keyboard *ppkb = i2c_get_clientdata(client); + unsigned short *keymap = ppkb->input->keycode; + int row_shift = get_count_order(PPKB_COLS); + u8 *old_buf = ppkb->buf[!ppkb->buf_swap]; + u8 *new_buf = ppkb->buf[ppkb->buf_swap]; + int col, crc, ret, row; + struct device *dev = &client->dev; + + ret = i2c_smbus_read_i2c_block_data(client, PPKB_SCAN_CRC, + PPKB_BUF_LEN, new_buf); + if (ret != PPKB_BUF_LEN) { + dev_err(dev, "Failed to read scan data: %d\n", ret); + return; + } + + crc = crc8(ppkb->crc_table, &new_buf[1], PPKB_COLS, CRC8_INIT_VALUE); + if (crc != new_buf[0]) { + dev_err(dev, "Bad scan data (%02x != %02x)\n", crc, new_buf[0]); + return; + } + + ppkb->buf_swap = !ppkb->buf_swap; + + for (col = 0; col < PPKB_COLS; ++col) { + u8 old = old_buf[1 + col]; + u8 new = new_buf[1 + col]; + u8 changed = old ^ new; + + if (!changed) + continue; + + for (row = 0; row < PPKB_ROWS; ++row) { + u8 mask = BIT(row); + u8 value = new & mask; + unsigned short code; + bool fn_state; + + if (!(changed & mask)) + continue; + + /* + * Save off the FN key state when the key was pressed, + * and use that to determine the code during a release. + */ + fn_state = value ? ppkb->fn_pressed : ppkb->fn_state[col] & mask; + if (fn_state) + ppkb->fn_state[col] ^= mask; + + /* The FN layer is a second set of rows. */ + code = MATRIX_SCAN_CODE(fn_state ? PPKB_ROWS + row : row, + col, row_shift); + input_event(ppkb->input, EV_MSC, MSC_SCAN, code); + input_report_key(ppkb->input, keymap[code], value); + if (keymap[code] == KEY_FN) + ppkb->fn_pressed = value; + } + } + input_sync(ppkb->input); +} + +static irqreturn_t ppkb_irq_thread(int irq, void *data) +{ + struct i2c_client *client = data; + + ppkb_update(client); + + return IRQ_HANDLED; +} + +static int ppkb_set_scan(struct i2c_client *client, bool enable) +{ + struct device *dev = &client->dev; + int ret, val; + + ret = i2c_smbus_read_byte_data(client, PPKB_SYS_CONFIG); + if (ret < 0) { + dev_err(dev, "Failed to read config: %d\n", ret); + return ret; + } + + if (enable) + val = ret & ~PPKB_SYS_CONFIG_DISABLE_SCAN; + else + val = ret | PPKB_SYS_CONFIG_DISABLE_SCAN; + + ret = i2c_smbus_write_byte_data(client, PPKB_SYS_CONFIG, val); + if (ret) { + dev_err(dev, "Failed to write config: %d\n", ret); + return ret; + } + + return 0; +} + +static int ppkb_open(struct input_dev *input) +{ + struct i2c_client *client = input_get_drvdata(input); + int error; + + error = ppkb_set_scan(client, true); + if (error) + return error; + + return 0; +} + +static void ppkb_close(struct input_dev *input) +{ + struct i2c_client *client = input_get_drvdata(input); + + ppkb_set_scan(client, false); +} + +static void ppkb_regulator_disable(void *regulator) +{ + regulator_disable(regulator); +} + +static int ppkb_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + unsigned int phys_rows, phys_cols; + struct pinephone_keyboard *ppkb; + struct regulator *vbat_supply; + u8 info[PPKB_MATRIX_SIZE + 1]; + int ret; + int error; + + vbat_supply = devm_regulator_get(dev, "vbat"); + error = PTR_ERR_OR_ZERO(vbat_supply); + if (error) { + dev_err(dev, "Failed to get VBAT supply: %d\n", error); + return error; + } + + error = regulator_enable(vbat_supply); + if (error) { + dev_err(dev, "Failed to enable VBAT: %d\n", error); + return error; + } + + error = devm_add_action_or_reset(dev, ppkb_regulator_disable, + vbat_supply); + if (error) + return error; + + ret = i2c_smbus_read_i2c_block_data(client, 0, sizeof(info), info); + if (ret != sizeof(info)) { + error = ret < 0 ? ret : -EIO; + dev_err(dev, "Failed to read device ID: %d\n", error); + return error; + } + + if (info[PPKB_DEVICE_ID_HI] != PPKB_DEVICE_ID_HI_VALUE || + info[PPKB_DEVICE_ID_LO] != PPKB_DEVICE_ID_LO_VALUE) { + dev_warn(dev, "Unexpected device ID: %#02x %#02x\n", + info[PPKB_DEVICE_ID_HI], info[PPKB_DEVICE_ID_LO]); + return -ENODEV; + } + + dev_info(dev, "Found firmware version %d.%d features %#x\n", + info[PPKB_FW_REVISION] >> 4, + info[PPKB_FW_REVISION] & 0xf, + info[PPKB_FW_FEATURES]); + + phys_rows = info[PPKB_MATRIX_SIZE] & 0xf; + phys_cols = info[PPKB_MATRIX_SIZE] >> 4; + if (phys_rows != PPKB_ROWS || phys_cols != PPKB_COLS) { + dev_err(dev, "Unexpected keyboard size %ux%u\n", + phys_rows, phys_cols); + return -EINVAL; + } + + /* Disable scan by default to save power. */ + error = ppkb_set_scan(client, false); + if (error) + return error; + + ppkb = devm_kzalloc(dev, sizeof(*ppkb), GFP_KERNEL); + if (!ppkb) + return -ENOMEM; + + i2c_set_clientdata(client, ppkb); + + crc8_populate_msb(ppkb->crc_table, PPKB_CRC8_POLYNOMIAL); + + ppkb->input = devm_input_allocate_device(dev); + if (!ppkb->input) + return -ENOMEM; + + input_set_drvdata(ppkb->input, client); + + ppkb->input->name = "PinePhone Keyboard"; + ppkb->input->phys = DRV_NAME "/input0"; + ppkb->input->id.bustype = BUS_I2C; + ppkb->input->open = ppkb_open; + ppkb->input->close = ppkb_close; + + input_set_capability(ppkb->input, EV_MSC, MSC_SCAN); + __set_bit(EV_REP, ppkb->input->evbit); + + error = matrix_keypad_build_keymap(&ppkb_keymap_data, NULL, + 2 * PPKB_ROWS, PPKB_COLS, NULL, + ppkb->input); + if (error) { + dev_err(dev, "Failed to build keymap: %d\n", error); + return error; + } + + error = input_register_device(ppkb->input); + if (error) { + dev_err(dev, "Failed to register input: %d\n", error); + return error; + } + + error = devm_request_threaded_irq(dev, client->irq, + NULL, ppkb_irq_thread, + IRQF_ONESHOT, client->name, client); + if (error) { + dev_err(dev, "Failed to request IRQ: %d\n", error); + return error; + } + + return 0; +} + +static const struct of_device_id ppkb_of_match[] = { + { .compatible = "pine64,pinephone-keyboard" }, + { } +}; +MODULE_DEVICE_TABLE(of, ppkb_of_match); + +static struct i2c_driver ppkb_driver = { + .probe_new = ppkb_probe, + .driver = { + .name = DRV_NAME, + .of_match_table = ppkb_of_match, + }, +}; +module_i2c_driver(ppkb_driver); + +MODULE_AUTHOR("Samuel Holland "); +MODULE_DESCRIPTION("Pine64 PinePhone keyboard driver"); +MODULE_LICENSE("GPL"); From 63c5eb157cfdb6f20387c4492d27d7248e239e85 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 30 Sep 2022 22:53:23 -0700 Subject: [PATCH 396/401] Input: pinephone-keyboard - support the proxied I2C bus The PinePhone keyboard case contains a battery managed by an integrated power bank IC. The power bank IC communicates over I2C, and the keyboard MCU firmware provides an interface to read and write its registers. Let's use this interface to implement a SMBus adapter, so we can reuse the driver for the power bank IC. Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20220618165747.55709-4-samuel@sholland.org Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/pinephone-keyboard.c | 76 +++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/drivers/input/keyboard/pinephone-keyboard.c b/drivers/input/keyboard/pinephone-keyboard.c index b10113b4b29b..5548699b8b38 100644 --- a/drivers/input/keyboard/pinephone-keyboard.c +++ b/drivers/input/keyboard/pinephone-keyboard.c @@ -3,6 +3,7 @@ // Copyright (C) 2021-2022 Samuel Holland #include +#include #include #include #include @@ -10,6 +11,7 @@ #include #include #include +#include #include #include @@ -28,6 +30,11 @@ #define PPKB_SCAN_DATA 0x08 #define PPKB_SYS_CONFIG 0x20 #define PPKB_SYS_CONFIG_DISABLE_SCAN BIT(0) +#define PPKB_SYS_SMBUS_COMMAND 0x21 +#define PPKB_SYS_SMBUS_DATA 0x22 +#define PPKB_SYS_COMMAND 0x23 +#define PPKB_SYS_COMMAND_SMBUS_READ 0x91 +#define PPKB_SYS_COMMAND_SMBUS_WRITE 0xa1 #define PPKB_ROWS 6 #define PPKB_COLS 12 @@ -136,6 +143,7 @@ static const struct matrix_keymap_data ppkb_keymap_data = { }; struct pinephone_keyboard { + struct i2c_adapter adapter; struct input_dev *input; u8 buf[2][PPKB_BUF_LEN]; u8 crc_table[CRC8_TABLE_SIZE]; @@ -144,6 +152,57 @@ struct pinephone_keyboard { bool fn_pressed; }; +static int ppkb_adap_smbus_xfer(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, + union i2c_smbus_data *data) +{ + struct i2c_client *client = adap->algo_data; + u8 buf[3]; + int ret; + + buf[0] = command; + buf[1] = data->byte; + buf[2] = read_write == I2C_SMBUS_READ ? PPKB_SYS_COMMAND_SMBUS_READ + : PPKB_SYS_COMMAND_SMBUS_WRITE; + + ret = i2c_smbus_write_i2c_block_data(client, PPKB_SYS_SMBUS_COMMAND, + sizeof(buf), buf); + if (ret) + return ret; + + /* Read back the command status until it passes or fails. */ + do { + usleep_range(300, 500); + ret = i2c_smbus_read_byte_data(client, PPKB_SYS_COMMAND); + } while (ret == buf[2]); + if (ret < 0) + return ret; + /* Commands return 0x00 on success and 0xff on failure. */ + if (ret) + return -EIO; + + if (read_write == I2C_SMBUS_READ) { + ret = i2c_smbus_read_byte_data(client, PPKB_SYS_SMBUS_DATA); + if (ret < 0) + return ret; + + data->byte = ret; + } + + return 0; +} + +static u32 ppkg_adap_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_SMBUS_BYTE_DATA; +} + +static const struct i2c_algorithm ppkb_adap_algo = { + .smbus_xfer = ppkb_adap_smbus_xfer, + .functionality = ppkg_adap_functionality, +}; + static void ppkb_update(struct i2c_client *client) { struct pinephone_keyboard *ppkb = i2c_get_clientdata(client); @@ -271,6 +330,7 @@ static int ppkb_probe(struct i2c_client *client) struct pinephone_keyboard *ppkb; struct regulator *vbat_supply; u8 info[PPKB_MATRIX_SIZE + 1]; + struct device_node *i2c_bus; int ret; int error; @@ -330,6 +390,22 @@ static int ppkb_probe(struct i2c_client *client) i2c_set_clientdata(client, ppkb); + i2c_bus = of_get_child_by_name(dev->of_node, "i2c"); + if (i2c_bus) { + ppkb->adapter.owner = THIS_MODULE; + ppkb->adapter.algo = &ppkb_adap_algo; + ppkb->adapter.algo_data = client; + ppkb->adapter.dev.parent = dev; + ppkb->adapter.dev.of_node = i2c_bus; + strscpy(ppkb->adapter.name, DRV_NAME, sizeof(ppkb->adapter.name)); + + error = devm_i2c_add_adapter(dev, &ppkb->adapter); + if (error) { + dev_err(dev, "Failed to add I2C adapter: %d\n", error); + return error; + } + } + crc8_populate_msb(ppkb->crc_table, PPKB_CRC8_POLYNOMIAL); ppkb->input = devm_input_allocate_device(dev); From 8761b9b580d53162cca7868385069c0d4354c9e0 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sat, 1 Oct 2022 14:28:34 -0700 Subject: [PATCH 397/401] Input: i8042 - rename i8042-x86ia64io.h to i8042-acpipnpio.h Now i8042-x86ia64io.h is shared by X86 and IA64, but it can be shared by more platforms (such as LoongArch) with ACPI firmware on which PNP typed keyboard and mouse is configured in DSDT. So rename it to i8042- acpipnpio.h. Signed-off-by: Huacai Chen Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20220917064020.1639709-1-chenhuacai@loongson.cn Signed-off-by: Dmitry Torokhov --- .../input/serio/{i8042-x86ia64io.h => i8042-acpipnpio.h} | 6 +++--- drivers/input/serio/i8042.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename drivers/input/serio/{i8042-x86ia64io.h => i8042-acpipnpio.h} (99%) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-acpipnpio.h similarity index 99% rename from drivers/input/serio/i8042-x86ia64io.h rename to drivers/input/serio/i8042-acpipnpio.h index 732b7a6b315d..e91c6a1814a8 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-acpipnpio.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef _I8042_X86IA64IO_H -#define _I8042_X86IA64IO_H +#ifndef _I8042_ACPIPNPIO_H +#define _I8042_ACPIPNPIO_H #ifdef CONFIG_X86 @@ -1665,4 +1665,4 @@ static inline void i8042_platform_exit(void) i8042_pnp_exit(); } -#endif /* _I8042_X86IA64IO_H */ +#endif /* _I8042_ACPIPNPIO_H */ diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index 55381783dc82..bf2592fa9a78 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h @@ -20,7 +20,7 @@ #elif defined(CONFIG_SPARC) #include "i8042-sparcio.h" #elif defined(CONFIG_X86) || defined(CONFIG_IA64) -#include "i8042-x86ia64io.h" +#include "i8042-acpipnpio.h" #else #include "i8042-io.h" #endif From fdd7c96176de823229d88e787b9e554b0f05b6c1 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sat, 1 Oct 2022 14:29:01 -0700 Subject: [PATCH 398/401] Input: i8042 - add LoongArch support in i8042-acpipnpio.h LoongArch uses ACPI and nearly the same as X86/IA64 for 8042. So modify i8042-acpipnpio.h slightly and enable it for LoongArch in i8042.h. Then i8042 driver can work well under the ACPI firmware with PNP typed key- board and mouse configured in DSDT. Signed-off-by: Huacai Chen Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20220917064020.1639709-2-chenhuacai@loongson.cn Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-acpipnpio.h | 6 ++++++ drivers/input/serio/i8042.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h index e91c6a1814a8..0778dc03cd9e 100644 --- a/drivers/input/serio/i8042-acpipnpio.h +++ b/drivers/input/serio/i8042-acpipnpio.h @@ -2,6 +2,7 @@ #ifndef _I8042_ACPIPNPIO_H #define _I8042_ACPIPNPIO_H +#include #ifdef CONFIG_X86 #include @@ -1453,9 +1454,14 @@ static int __init i8042_pnp_init(void) return -ENODEV; #else pr_info("PNP: No PS/2 controller found.\n"); +#if defined(__loongarch__) + if (acpi_disabled == 0) + return -ENODEV; +#else if (x86_platform.legacy.i8042 != X86_LEGACY_I8042_EXPECTED_PRESENT) return -ENODEV; +#endif pr_info("Probing ports directly.\n"); return 0; #endif diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index bf2592fa9a78..adb5173372d3 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h @@ -19,7 +19,7 @@ #include "i8042-snirm.h" #elif defined(CONFIG_SPARC) #include "i8042-sparcio.h" -#elif defined(CONFIG_X86) || defined(CONFIG_IA64) +#elif defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_LOONGARCH) #include "i8042-acpipnpio.h" #else #include "i8042-io.h" From fe5b6aaef72a0f7daa06e7960e0bee45c2984e41 Mon Sep 17 00:00:00 2001 From: Liang He Date: Sat, 1 Oct 2022 14:42:24 -0700 Subject: [PATCH 399/401] Input: i8042 - fix refount leak on sparc In i8042_platform_init() and i8042_platform_exit(), we should call of_node_put() for the reference 'root' returned by of_find_node_by_path() which has increased the refcount. Fixes: f57caaefacc2 ("[SERIO] i8042-sparcio.h: Convert to of_driver framework.") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220711064300.358757-1-windhl@126.com [dtor: rearranged i8042_is_mr_coffee() a bit] Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-sparcio.h | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index fce76812843b..c712c1fe0605 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -3,6 +3,7 @@ #define _I8042_SPARCIO_H #include +#include #include #include @@ -103,12 +104,25 @@ static struct platform_driver sparc_i8042_driver = { .remove = sparc_i8042_remove, }; +static bool i8042_is_mr_coffee(void) +{ + struct device_node *root; + const char *name; + bool is_mr_coffee; + + root = of_find_node_by_path("/"); + + name = of_get_property(root, "name", NULL); + is_mr_coffee = name && !strcmp(name, "SUNW,JavaStation-1"); + + of_node_put(root); + + return is_mr_coffee; +} + static int __init i8042_platform_init(void) { - struct device_node *root = of_find_node_by_path("/"); - const char *name = of_get_property(root, "name", NULL); - - if (name && !strcmp(name, "SUNW,JavaStation-1")) { + if (i8042_is_mr_coffee()) { /* Hardcoded values for MrCoffee. */ i8042_kbd_irq = i8042_aux_irq = 13 | 0x20; kbd_iobase = ioremap(0x71300060, 8); @@ -136,10 +150,7 @@ static int __init i8042_platform_init(void) static inline void i8042_platform_exit(void) { - struct device_node *root = of_find_node_by_path("/"); - const char *name = of_get_property(root, "name", NULL); - - if (!name || strcmp(name, "SUNW,JavaStation-1")) + if (!i8042_is_mr_coffee()) platform_driver_unregister(&sparc_i8042_driver); } From ae5b6779fa8724628bbad58126a626d0cd599414 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 11 Oct 2022 14:29:10 +1030 Subject: [PATCH 400/401] powerpc: Fix 85xx build The merge of the kbuild tree dropped the renaming of the FSL_BOOKE kconfig option. Fixes: 8afc66e8d43b ("Merge tag 'kbuild-v6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild") Signed-off-by: Joel Stanley Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 68ea30fb373e..ee2d76cb3187 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -121,7 +121,7 @@ obj-$(CONFIG_PPC_BOOK3S_32) += head_book3s_32.o obj-$(CONFIG_40x) += head_40x.o obj-$(CONFIG_44x) += head_44x.o obj-$(CONFIG_PPC_8xx) += head_8xx.o -obj-$(CONFIG_FSL_BOOKE) += head_85xx.o +obj-$(CONFIG_PPC_85xx) += head_85xx.o extra-y += vmlinux.lds obj-$(CONFIG_RELOCATABLE) += reloc_$(BITS).o From c6cc4f7241d92cfdc36f9a13dfe318492f7eaa73 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 4 Oct 2022 09:13:02 +0200 Subject: [PATCH 401/401] alpha: remove the needless aliases osf_{readv,writev} Commit 987f20a9dcce ("a.out: Remove the a.out implementation") removes CONFIG_OSF4_COMPAT and its functionality. Hence, sys_osf_{readv,writev} are now just aliases of sys_{readv,writev}. Remove these needless aliases. [ Identical patch also posted by Jason A. Donenfeld ] Link: https://lore.kernel.org/lkml/CAHk-=wjwvBc3VQMNtUVUrMBVoMPSPu26OuatZ_+1gZ2m-PmmRA@mail.gmail.com/ Link: https://lore.kernel.org/all/20221004135301.1420873-1-Jason@zx2c4.com/ Suggested-by: Linus Torvalds Signed-off-by: Lukas Bulwahn Signed-off-by: Linus Torvalds --- arch/alpha/kernel/osf_sys.c | 12 ------------ arch/alpha/kernel/syscalls/syscall.tbl | 4 ++-- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 68ec314d3fac..c54469b369cb 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -1278,18 +1278,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, return addr; } -SYSCALL_DEFINE3(osf_readv, unsigned long, fd, - const struct iovec __user *, vector, unsigned long, count) -{ - return sys_readv(fd, vector, count); -} - -SYSCALL_DEFINE3(osf_writev, unsigned long, fd, - const struct iovec __user *, vector, unsigned long, count) -{ - return sys_writev(fd, vector, count); -} - SYSCALL_DEFINE2(osf_getpriority, int, which, int, who) { int prio = sys_getpriority(which, who); diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl index 3515bc4f16a4..8ebacf37a8cf 100644 --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@ -125,8 +125,8 @@ 116 common osf_gettimeofday sys_osf_gettimeofday 117 common osf_getrusage sys_osf_getrusage 118 common getsockopt sys_getsockopt -120 common readv sys_osf_readv -121 common writev sys_osf_writev +120 common readv sys_readv +121 common writev sys_writev 122 common osf_settimeofday sys_osf_settimeofday 123 common fchown sys_fchown 124 common fchmod sys_fchmod