From 0268d4579901821ff17259213c2d8c9679995d48 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Fri, 1 Nov 2024 19:15:57 +0500 Subject: [PATCH 01/16] selftests: hugetlb_dio: check for initial conditions to skip in the start The test should be skipped if initial conditions aren't fulfilled in the start instead of failing and outputting non-compliant TAP logs. This kind of failure pollutes the results. The initial conditions are: - The test should only execute if /tmp file can be allocated. - The test should only execute if huge pages are free. Before: TAP version 13 1..4 Bail out! Error opening file : Read-only file system (30) # Planned tests != run tests (4 != 0) # Totals: pass:0 fail:0 xfail:0 xpass:0 skip:0 error:0 After: TAP version 13 1..0 # SKIP Unable to allocate file: Read-only file system Link: https://lkml.kernel.org/r/20241101141557.3159432-1-usama.anjum@collabora.com Signed-off-by: Muhammad Usama Anjum Fixes: 3a103b5315b7 ("selftest: mm: Test if hugepage does not get leaked during __bio_release_pages()") Cc: Muhammad Usama Anjum Cc: Shuah Khan Cc: Donet Tom Cc: Signed-off-by: Andrew Morton --- tools/testing/selftests/mm/hugetlb_dio.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/mm/hugetlb_dio.c b/tools/testing/selftests/mm/hugetlb_dio.c index f9ac20c657ec..60001c142ce9 100644 --- a/tools/testing/selftests/mm/hugetlb_dio.c +++ b/tools/testing/selftests/mm/hugetlb_dio.c @@ -44,13 +44,6 @@ void run_dio_using_hugetlb(unsigned int start_off, unsigned int end_off) if (fd < 0) ksft_exit_fail_perror("Error opening file\n"); - /* Get the free huge pages before allocation */ - free_hpage_b = get_free_hugepages(); - if (free_hpage_b == 0) { - close(fd); - ksft_exit_skip("No free hugepage, exiting!\n"); - } - /* Allocate a hugetlb page */ orig_buffer = mmap(NULL, h_pagesize, mmap_prot, mmap_flags, -1, 0); if (orig_buffer == MAP_FAILED) { @@ -94,8 +87,20 @@ void run_dio_using_hugetlb(unsigned int start_off, unsigned int end_off) int main(void) { size_t pagesize = 0; + int fd; ksft_print_header(); + + /* Open the file to DIO */ + fd = open("/tmp", O_TMPFILE | O_RDWR | O_DIRECT, 0664); + if (fd < 0) + ksft_exit_skip("Unable to allocate file: %s\n", strerror(errno)); + close(fd); + + /* Check if huge pages are free */ + if (!get_free_hugepages()) + ksft_exit_skip("No free hugepage, exiting\n"); + ksft_set_plan(4); /* Get base page size */ -- 2.51.0 From 432dc0654c612457285a5dcf9bb13968ac6f0804 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Fri, 1 Nov 2024 19:19:40 +0000 Subject: [PATCH 02/16] ucounts: fix counter leak in inc_rlimit_get_ucounts() The inc_rlimit_get_ucounts() increments the specified rlimit counter and then checks its limit. If the value exceeds the limit, the function returns an error without decrementing the counter. Link: https://lkml.kernel.org/r/20241101191940.3211128-1-roman.gushchin@linux.dev Fixes: 15bc01effefe ("ucounts: Fix signal ucount refcounting") Signed-off-by: Andrei Vagin Co-developed-by: Roman Gushchin Signed-off-by: Roman Gushchin Tested-by: Roman Gushchin Acked-by: Alexey Gladkov Cc: Kees Cook Cc: Andrei Vagin Cc: "Eric W. Biederman" Cc: Alexey Gladkov Cc: Oleg Nesterov Cc: Signed-off-by: Andrew Morton --- kernel/ucount.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/ucount.c b/kernel/ucount.c index 8c07714ff27d..9469102c5ac0 100644 --- a/kernel/ucount.c +++ b/kernel/ucount.c @@ -317,7 +317,7 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type) for (iter = ucounts; iter; iter = iter->ns->ucounts) { long new = atomic_long_add_return(1, &iter->rlimit[type]); if (new < 0 || new > max) - goto unwind; + goto dec_unwind; if (iter == ucounts) ret = new; max = get_userns_rlimit_max(iter->ns, type); @@ -334,7 +334,6 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type) dec_unwind: dec = atomic_long_sub_return(1, &iter->rlimit[type]); WARN_ON_ONCE(dec < 0); -unwind: do_dec_rlimit_put_ucounts(ucounts, iter, type); return 0; } -- 2.51.0 From b8ee299855f08539e04d6c1a6acb3dc9e5423c00 Mon Sep 17 00:00:00 2001 From: Qi Xi Date: Fri, 1 Nov 2024 11:48:03 +0800 Subject: [PATCH 03/16] fs/proc: fix compile warning about variable 'vmcore_mmap_ops' When build with !CONFIG_MMU, the variable 'vmcore_mmap_ops' is defined but not used: >> fs/proc/vmcore.c:458:42: warning: unused variable 'vmcore_mmap_ops' 458 | static const struct vm_operations_struct vmcore_mmap_ops = { Fix this by only defining it when CONFIG_MMU is enabled. Link: https://lkml.kernel.org/r/20241101034803.9298-1-xiqi2@huawei.com Fixes: 9cb218131de1 ("vmcore: introduce remap_oldmem_pfn_range()") Signed-off-by: Qi Xi Reported-by: kernel test robot Closes: https://lore.kernel.org/lkml/202410301936.GcE8yUos-lkp@intel.com/ Cc: Baoquan He Cc: Dave Young Cc: Michael Holzheu Cc: Vivek Goyal Cc: Wang ShaoBo Signed-off-by: Andrew Morton --- fs/proc/vmcore.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index b52d85f8ad59..b4521b096058 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -457,10 +457,6 @@ static vm_fault_t mmap_vmcore_fault(struct vm_fault *vmf) #endif } -static const struct vm_operations_struct vmcore_mmap_ops = { - .fault = mmap_vmcore_fault, -}; - /** * vmcore_alloc_buf - allocate buffer in vmalloc memory * @size: size of buffer @@ -488,6 +484,11 @@ static inline char *vmcore_alloc_buf(size_t size) * virtually contiguous user-space in ELF layout. */ #ifdef CONFIG_MMU + +static const struct vm_operations_struct vmcore_mmap_ops = { + .fault = mmap_vmcore_fault, +}; + /* * remap_oldmem_pfn_checked - do remap_oldmem_pfn_range replacing all pages * reported as not being ram with the zero page. -- 2.51.0 From 9e05e5c7ee8758141d2db7e8fea2cab34500c6ed Mon Sep 17 00:00:00 2001 From: Roman Gushchin Date: Mon, 4 Nov 2024 19:54:19 +0000 Subject: [PATCH 04/16] signal: restore the override_rlimit logic Prior to commit d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts") UCOUNT_RLIMIT_SIGPENDING rlimit was not enforced for a class of signals. However now it's enforced unconditionally, even if override_rlimit is set. This behavior change caused production issues. For example, if the limit is reached and a process receives a SIGSEGV signal, sigqueue_alloc fails to allocate the necessary resources for the signal delivery, preventing the signal from being delivered with siginfo. This prevents the process from correctly identifying the fault address and handling the error. From the user-space perspective, applications are unaware that the limit has been reached and that the siginfo is effectively 'corrupted'. This can lead to unpredictable behavior and crashes, as we observed with java applications. Fix this by passing override_rlimit into inc_rlimit_get_ucounts() and skip the comparison to max there if override_rlimit is set. This effectively restores the old behavior. Link: https://lkml.kernel.org/r/20241104195419.3962584-1-roman.gushchin@linux.dev Fixes: d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts") Signed-off-by: Roman Gushchin Co-developed-by: Andrei Vagin Signed-off-by: Andrei Vagin Acked-by: Oleg Nesterov Acked-by: Alexey Gladkov Cc: Kees Cook Cc: "Eric W. Biederman" Cc: Signed-off-by: Andrew Morton --- include/linux/user_namespace.h | 3 ++- kernel/signal.c | 3 ++- kernel/ucount.c | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index 3625096d5f85..7183e5aca282 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -141,7 +141,8 @@ static inline long get_rlimit_value(struct ucounts *ucounts, enum rlimit_type ty long inc_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v); bool dec_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v); -long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type); +long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type, + bool override_rlimit); void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum rlimit_type type); bool is_rlimit_overlimit(struct ucounts *ucounts, enum rlimit_type type, unsigned long max); diff --git a/kernel/signal.c b/kernel/signal.c index 4344860ffcac..cbabb2d05e0a 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -419,7 +419,8 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags, */ rcu_read_lock(); ucounts = task_ucounts(t); - sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING); + sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, + override_rlimit); rcu_read_unlock(); if (!sigpending) return NULL; diff --git a/kernel/ucount.c b/kernel/ucount.c index 9469102c5ac0..696406939be5 100644 --- a/kernel/ucount.c +++ b/kernel/ucount.c @@ -307,7 +307,8 @@ void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum rlimit_type type) do_dec_rlimit_put_ucounts(ucounts, NULL, type); } -long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type) +long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type, + bool override_rlimit) { /* Caller must hold a reference to ucounts */ struct ucounts *iter; @@ -320,7 +321,8 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type) goto dec_unwind; if (iter == ucounts) ret = new; - max = get_userns_rlimit_max(iter->ns, type); + if (!override_rlimit) + max = get_userns_rlimit_max(iter->ns, type); /* * Grab an extra ucount reference for the caller when * the rlimit count was previously 0. -- 2.51.0 From 0b63c0e01fba40e3992bc627272ec7b618ccaef7 Mon Sep 17 00:00:00 2001 From: Andrew Kanner Date: Sun, 3 Nov 2024 20:38:45 +0100 Subject: [PATCH 05/16] ocfs2: remove entry once instead of null-ptr-dereference in ocfs2_xa_remove() Syzkaller is able to provoke null-ptr-dereference in ocfs2_xa_remove(): [ 57.319872] (a.out,1161,7):ocfs2_xa_remove:2028 ERROR: status = -12 [ 57.320420] (a.out,1161,7):ocfs2_xa_cleanup_value_truncate:1999 ERROR: Partial truncate while removing xattr overlay.upper. Leaking 1 clusters and removing the entry [ 57.321727] BUG: kernel NULL pointer dereference, address: 0000000000000004 [...] [ 57.325727] RIP: 0010:ocfs2_xa_block_wipe_namevalue+0x2a/0xc0 [...] [ 57.331328] Call Trace: [ 57.331477] [...] [ 57.333511] ? do_user_addr_fault+0x3e5/0x740 [ 57.333778] ? exc_page_fault+0x70/0x170 [ 57.334016] ? asm_exc_page_fault+0x2b/0x30 [ 57.334263] ? __pfx_ocfs2_xa_block_wipe_namevalue+0x10/0x10 [ 57.334596] ? ocfs2_xa_block_wipe_namevalue+0x2a/0xc0 [ 57.334913] ocfs2_xa_remove_entry+0x23/0xc0 [ 57.335164] ocfs2_xa_set+0x704/0xcf0 [ 57.335381] ? _raw_spin_unlock+0x1a/0x40 [ 57.335620] ? ocfs2_inode_cache_unlock+0x16/0x20 [ 57.335915] ? trace_preempt_on+0x1e/0x70 [ 57.336153] ? start_this_handle+0x16c/0x500 [ 57.336410] ? preempt_count_sub+0x50/0x80 [ 57.336656] ? _raw_read_unlock+0x20/0x40 [ 57.336906] ? start_this_handle+0x16c/0x500 [ 57.337162] ocfs2_xattr_block_set+0xa6/0x1e0 [ 57.337424] __ocfs2_xattr_set_handle+0x1fd/0x5d0 [ 57.337706] ? ocfs2_start_trans+0x13d/0x290 [ 57.337971] ocfs2_xattr_set+0xb13/0xfb0 [ 57.338207] ? dput+0x46/0x1c0 [ 57.338393] ocfs2_xattr_trusted_set+0x28/0x30 [ 57.338665] ? ocfs2_xattr_trusted_set+0x28/0x30 [ 57.338948] __vfs_removexattr+0x92/0xc0 [ 57.339182] __vfs_removexattr_locked+0xd5/0x190 [ 57.339456] ? preempt_count_sub+0x50/0x80 [ 57.339705] vfs_removexattr+0x5f/0x100 [...] Reproducer uses faultinject facility to fail ocfs2_xa_remove() -> ocfs2_xa_value_truncate() with -ENOMEM. In this case the comment mentions that we can return 0 if ocfs2_xa_cleanup_value_truncate() is going to wipe the entry anyway. But the following 'rc' check is wrong and execution flow do 'ocfs2_xa_remove_entry(loc);' twice: * 1st: in ocfs2_xa_cleanup_value_truncate(); * 2nd: returning back to ocfs2_xa_remove() instead of going to 'out'. Fix this by skipping the 2nd removal of the same entry and making syzkaller repro happy. Link: https://lkml.kernel.org/r/20241103193845.2940988-1-andrew.kanner@gmail.com Fixes: 399ff3a748cf ("ocfs2: Handle errors while setting external xattr values.") Signed-off-by: Andrew Kanner Reported-by: syzbot+386ce9e60fa1b18aac5b@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/671e13ab.050a0220.2b8c0f.01d0.GAE@google.com/T/ Tested-by: syzbot+386ce9e60fa1b18aac5b@syzkaller.appspotmail.com Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Jun Piao Cc: Signed-off-by: Andrew Morton --- fs/ocfs2/xattr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index dd0a05365e79..73a6f6fd8a8e 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -2036,8 +2036,7 @@ static int ocfs2_xa_remove(struct ocfs2_xa_loc *loc, rc = 0; ocfs2_xa_cleanup_value_truncate(loc, "removing", orig_clusters); - if (rc) - goto out; + goto out; } } -- 2.51.0 From c289f4de8e479251b64988839fd0e87f246e03a2 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 4 Nov 2024 00:44:09 +0100 Subject: [PATCH 06/16] mailmap: add entry for Thorsten Blum Map my previously used email address to my @linux.dev address. Link: https://lkml.kernel.org/r/20241103234411.2522-2-thorsten.blum@linux.dev Signed-off-by: Thorsten Blum Cc: Alex Elder Cc: David S. Miller Cc: Geliang Tang Cc: Kees Cook Cc: Mathieu Othacehe Cc: Matthieu Baerts (NGI0) Cc: Matt Ranostay Cc: Naoya Horiguchi Cc: Neeraj Upadhyay Cc: Quentin Monnet Signed-off-by: Andrew Morton --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 5378f04b2566..5e829da09e7f 100644 --- a/.mailmap +++ b/.mailmap @@ -665,6 +665,7 @@ Tomeu Vizoso Thomas Graf Thomas Körper Thomas Pedersen +Thorsten Blum Tiezhu Yang Tingwei Zhang Tirupathi Reddy -- 2.51.0 From 8de3e97f3d3d62cd9f3067f073e8ac93261597db Mon Sep 17 00:00:00 2001 From: Liu Peibao Date: Fri, 1 Nov 2024 16:12:43 +0800 Subject: [PATCH 07/16] i2c: designware: do not hold SCL low when I2C_DYNAMIC_TAR_UPDATE is not set When the Tx FIFO is empty and the last command has no STOP bit set, the master holds SCL low. If I2C_DYNAMIC_TAR_UPDATE is not set, BIT(13) MST_ON_HOLD of IC_RAW_INTR_STAT is not enabled, causing the __i2c_dw_disable() timeout. This is quite similar to commit 2409205acd3c ("i2c: designware: fix __i2c_dw_disable() in case master is holding SCL low"). Also check BIT(7) MST_HOLD_TX_FIFO_EMPTY in IC_STATUS, which is available when IC_STAT_FOR_CLK_STRETCH is set. Fixes: 2409205acd3c ("i2c: designware: fix __i2c_dw_disable() in case master is holding SCL low") Co-developed-by: Xiaowu Ding Signed-off-by: Xiaowu Ding Co-developed-by: Angus Chen Signed-off-by: Angus Chen Signed-off-by: Liu Peibao Acked-by: Jarkko Nikula Signed-off-by: Andi Shyti --- drivers/i2c/busses/i2c-designware-common.c | 6 ++++-- drivers/i2c/busses/i2c-designware-core.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index f31d352d98b5..9d88b4fa03e4 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -524,7 +524,7 @@ err_release_lock: void __i2c_dw_disable(struct dw_i2c_dev *dev) { struct i2c_timings *t = &dev->timings; - unsigned int raw_intr_stats; + unsigned int raw_intr_stats, ic_stats; unsigned int enable; int timeout = 100; bool abort_needed; @@ -532,9 +532,11 @@ void __i2c_dw_disable(struct dw_i2c_dev *dev) int ret; regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats); + regmap_read(dev->map, DW_IC_STATUS, &ic_stats); regmap_read(dev->map, DW_IC_ENABLE, &enable); - abort_needed = raw_intr_stats & DW_IC_INTR_MST_ON_HOLD; + abort_needed = (raw_intr_stats & DW_IC_INTR_MST_ON_HOLD) || + (ic_stats & DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY); if (abort_needed) { if (!(enable & DW_IC_ENABLE_ENABLE)) { regmap_write(dev->map, DW_IC_ENABLE, DW_IC_ENABLE_ENABLE); diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 8e8854ec9882..2d32896d0673 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -116,6 +116,7 @@ #define DW_IC_STATUS_RFNE BIT(3) #define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) #define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) +#define DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY BIT(7) #define DW_IC_SDA_HOLD_RX_SHIFT 16 #define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, 16) -- 2.51.0 From ace149e0830c380ddfce7e466fe860ca502fe4ee Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 13 Sep 2024 13:57:04 -0400 Subject: [PATCH 08/16] filemap: Fix bounds checking in filemap_read() If the caller supplies an iocb->ki_pos value that is close to the filesystem upper limit, and an iterator with a count that causes us to overflow that limit, then filemap_read() enters an infinite loop. This behaviour was discovered when testing xfstests generic/525 with the "localio" optimisation for loopback NFS mounts. Reported-by: Mike Snitzer Fixes: c2a9737f45e2 ("vfs,mm: fix a dead loop in truncate_inode_pages_range()") Tested-by: Mike Snitzer Signed-off-by: Trond Myklebust Signed-off-by: Linus Torvalds --- mm/filemap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/filemap.c b/mm/filemap.c index 36d22968be9a..56fa431c52af 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2625,7 +2625,7 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, if (unlikely(!iov_iter_count(iter))) return 0; - iov_iter_truncate(iter, inode->i_sb->s_maxbytes); + iov_iter_truncate(iter, inode->i_sb->s_maxbytes - iocb->ki_pos); folio_batch_init(&fbatch); do { -- 2.51.0 From 2d5404caa8c7bb5c4e0435f94b28834ae5456623 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 10 Nov 2024 14:19:35 -0800 Subject: [PATCH 09/16] Linux 6.12-rc7 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b8efbfe9da94..79192a3024bf 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 6 PATCHLEVEL = 12 SUBLEVEL = 0 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc7 NAME = Baby Opossum Posse # *DOCUMENTATION* -- 2.51.0 From a7e03f96791e098ebde43acce6b04283f10815db Mon Sep 17 00:00:00 2001 From: =?utf8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 18 Sep 2024 14:31:49 +0200 Subject: [PATCH 10/16] hwmon: Drop explicit initialization of struct i2c_device_id::driver_data to 0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit These drivers don't use the driver_data member of struct i2c_device_id, so don't explicitly initialize this member. This prepares putting driver_data in an anonymous union which requires either no initialization or named designators. But it's also a nice cleanup on its own. While touching these structs, also remove commas after the sentinel entries and use a consistent indention style. Signed-off-by: Uwe Kleine-König Message-ID: <20240918123150.1540161-7-u.kleine-koenig@baylibre.com> Signed-off-by: Guenter Roeck --- drivers/hwmon/amc6821.c | 2 +- drivers/hwmon/pmbus/mp2891.c | 4 ++-- drivers/hwmon/pmbus/mp2993.c | 4 ++-- drivers/hwmon/pmbus/mp9941.c | 4 ++-- drivers/hwmon/sg2042-mcu.c | 4 ++-- drivers/hwmon/spd5118.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index ac64b407ed0e..e86027f850c9 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c @@ -927,7 +927,7 @@ static int amc6821_probe(struct i2c_client *client) } static const struct i2c_device_id amc6821_id[] = { - { "amc6821", 0 }, + { "amc6821" }, { } }; diff --git a/drivers/hwmon/pmbus/mp2891.c b/drivers/hwmon/pmbus/mp2891.c index bb28b15a9103..94ab4ae5fba0 100644 --- a/drivers/hwmon/pmbus/mp2891.c +++ b/drivers/hwmon/pmbus/mp2891.c @@ -572,8 +572,8 @@ static int mp2891_probe(struct i2c_client *client) } static const struct i2c_device_id mp2891_id[] = { - {"mp2891", 0}, - {} + { "mp2891" }, + { } }; MODULE_DEVICE_TABLE(i2c, mp2891_id); diff --git a/drivers/hwmon/pmbus/mp2993.c b/drivers/hwmon/pmbus/mp2993.c index 944593e13231..63691dac2281 100644 --- a/drivers/hwmon/pmbus/mp2993.c +++ b/drivers/hwmon/pmbus/mp2993.c @@ -233,8 +233,8 @@ static int mp2993_probe(struct i2c_client *client) } static const struct i2c_device_id mp2993_id[] = { - {"mp2993", 0}, - {} + { "mp2993" }, + { } }; MODULE_DEVICE_TABLE(i2c, mp2993_id); diff --git a/drivers/hwmon/pmbus/mp9941.c b/drivers/hwmon/pmbus/mp9941.c index 543955cfce67..8ab5fc4d4092 100644 --- a/drivers/hwmon/pmbus/mp9941.c +++ b/drivers/hwmon/pmbus/mp9941.c @@ -291,8 +291,8 @@ static int mp9941_probe(struct i2c_client *client) } static const struct i2c_device_id mp9941_id[] = { - {"mp9941", 0}, - {} + { "mp9941" }, + { } }; MODULE_DEVICE_TABLE(i2c, mp9941_id); diff --git a/drivers/hwmon/sg2042-mcu.c b/drivers/hwmon/sg2042-mcu.c index 141045769354..aa3fb773602c 100644 --- a/drivers/hwmon/sg2042-mcu.c +++ b/drivers/hwmon/sg2042-mcu.c @@ -346,8 +346,8 @@ static void sg2042_mcu_i2c_remove(struct i2c_client *client) } static const struct i2c_device_id sg2042_mcu_id[] = { - { "sg2042-hwmon-mcu", 0 }, - {}, + { "sg2042-hwmon-mcu" }, + { } }; MODULE_DEVICE_TABLE(i2c, sg2042_mcu_id); diff --git a/drivers/hwmon/spd5118.c b/drivers/hwmon/spd5118.c index fcbce5a01e55..6cee48a3e5c3 100644 --- a/drivers/hwmon/spd5118.c +++ b/drivers/hwmon/spd5118.c @@ -671,7 +671,7 @@ static int spd5118_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(spd5118_pm_ops, spd5118_suspend, spd5118_resume); static const struct i2c_device_id spd5118_id[] = { - { "spd5118", 0 }, + { "spd5118" }, { } }; MODULE_DEVICE_TABLE(i2c, spd5118_id); -- 2.51.0 From de0da6ae1908b43b23782d64b4564b5ca3119f7f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 27 Aug 2024 12:57:10 -0700 Subject: [PATCH 11/16] hwmon: (ina2xx) Add support for has_alerts configuration flag Add configuration flag indicating if the chip supports alerts and limits to prepare for adding INA260 support. Reviewed-by: Tzung-Bi Shih Signed-off-by: Guenter Roeck --- drivers/hwmon/ina2xx.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index f0fa6d073627..03a011c9b73d 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -129,6 +129,7 @@ enum ina2xx_ids { ina219, ina226 }; struct ina2xx_config { u16 config_default; + bool has_alerts; /* chip supports alerts and limits */ int calibration_value; int shunt_div; int bus_voltage_shift; @@ -155,6 +156,7 @@ static const struct ina2xx_config ina2xx_config[] = { .bus_voltage_shift = 3, .bus_voltage_lsb = 4000, .power_lsb_factor = 20, + .has_alerts = false, }, [ina226] = { .config_default = INA226_CONFIG_DEFAULT, @@ -163,6 +165,7 @@ static const struct ina2xx_config ina2xx_config[] = { .bus_voltage_shift = 0, .bus_voltage_lsb = 1250, .power_lsb_factor = 25, + .has_alerts = true, }, }; @@ -624,6 +627,7 @@ static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type u32 attr, int channel) { const struct ina2xx_data *data = _data; + bool has_alerts = data->config->has_alerts; enum ina2xx_ids chip = data->chip; switch (type) { @@ -633,12 +637,12 @@ static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type return 0444; case hwmon_in_lcrit: case hwmon_in_crit: - if (chip == ina226) + if (has_alerts) return 0644; break; case hwmon_in_lcrit_alarm: case hwmon_in_crit_alarm: - if (chip == ina226) + if (has_alerts) return 0444; break; default: @@ -651,12 +655,12 @@ static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type return 0444; case hwmon_curr_lcrit: case hwmon_curr_crit: - if (chip == ina226) + if (has_alerts) return 0644; break; case hwmon_curr_lcrit_alarm: case hwmon_curr_crit_alarm: - if (chip == ina226) + if (has_alerts) return 0444; break; default: @@ -668,11 +672,11 @@ static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type case hwmon_power_input: return 0444; case hwmon_power_crit: - if (chip == ina226) + if (has_alerts) return 0644; break; case hwmon_power_crit_alarm: - if (chip == ina226) + if (has_alerts) return 0444; break; default: @@ -802,7 +806,7 @@ static int ina2xx_init(struct device *dev, struct ina2xx_data *data) if (ret < 0) return ret; - if (data->chip == ina226) { + if (data->config->has_alerts) { bool active_high = device_property_read_bool(dev, "ti,alert-polarity-active-high"); regmap_update_bits(regmap, INA226_MASK_ENABLE, -- 2.51.0 From 70fb84a109c639637f0636281dbdb21ed8ffb000 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 27 Aug 2024 10:23:10 -0700 Subject: [PATCH 12/16] hwmon: (ina2xx) Add support for INA260 INA260 is similar to other chips of the series, except it has an internal shunt resistor. The calibration register is therefore not present. Also, the current register address was changed, though that does not matter for the driver since the shunt voltage register (which is now the current register) value is already used to read the current. Cc: Loic Guegan Reviewed-by: Tzung-Bi Shih Signed-off-by: Guenter Roeck --- Documentation/hwmon/ina2xx.rst | 23 +++++++++++++++---- drivers/hwmon/Kconfig | 5 ++-- drivers/hwmon/ina2xx.c | 42 ++++++++++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/Documentation/hwmon/ina2xx.rst b/Documentation/hwmon/ina2xx.rst index 7f1939b40f74..1ce161e6c0bf 100644 --- a/Documentation/hwmon/ina2xx.rst +++ b/Documentation/hwmon/ina2xx.rst @@ -53,6 +53,16 @@ Supported chips: https://www.ti.com/ + * Texas Instruments INA260 + + Prefix: 'ina260' + + Addresses: I2C 0x40 - 0x4f + + Datasheet: Publicly available at the Texas Instruments website + + https://www.ti.com/ + Author: Lothar Felten Description @@ -72,6 +82,9 @@ INA230 and INA231 are high or low side current shunt and power monitors with an I2C interface. The chips monitor both a shunt voltage drop and bus supply voltage. +INA260 is a high or low side current and power monitor with integrated shunt +resistor. + The shunt value in micro-ohms can be set via platform data or device tree at compile-time or via the shunt_resistor attribute in sysfs at run-time. Please refer to the Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml for bindings @@ -87,16 +100,16 @@ The actual programmed interval may vary from the desired value. General sysfs entries --------------------- -======================= =============================== +======================= =============================================== in0_input Shunt voltage(mV) channel in1_input Bus voltage(mV) channel curr1_input Current(mA) measurement channel power1_input Power(uW) measurement channel -shunt_resistor Shunt resistance(uOhm) channel -======================= =============================== +shunt_resistor Shunt resistance(uOhm) channel (not for ina260) +======================= =============================================== -Sysfs entries for ina226, ina230 and ina231 only ------------------------------------------------- +Additional sysfs entries for ina226, ina230, ina231, and ina260 +--------------------------------------------------------------- ======================= ==================================================== curr1_lcrit Critical low current diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 08a3c863f80a..6a3385598cc6 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -2167,11 +2167,12 @@ config SENSORS_INA2XX select REGMAP_I2C help If you say yes here you get support for INA219, INA220, INA226, - INA230, and INA231 power monitor chips. + INA230, INA231, and INA260 power monitor chips. The INA2xx driver is configured for the default configuration of the part as described in the datasheet. - Default value for Rshunt is 10 mOhms. + Default value for Rshunt is 10 mOhms except for INA260 which has an + internal 2 mOhm shunt resistor. This driver can also be built as a module. If so, the module will be called ina2xx. diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 03a011c9b73d..cecc80a41a97 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -56,12 +56,14 @@ /* settings - depend on use case */ #define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ #define INA226_CONFIG_DEFAULT 0x4527 /* averages=16 */ +#define INA260_CONFIG_DEFAULT 0x6527 /* averages=16 */ /* worst case is 68.10 ms (~14.6Hz, ina219) */ #define INA2XX_CONVERSION_RATE 15 #define INA2XX_MAX_DELAY 69 /* worst case delay in ms */ #define INA2XX_RSHUNT_DEFAULT 10000 +#define INA260_RSHUNT 2000 /* bit mask for reading the averaging setting in the configuration register */ #define INA226_AVG_RD_MASK GENMASK(11, 9) @@ -125,11 +127,12 @@ static const struct regmap_config ina2xx_regmap_config = { .writeable_reg = ina2xx_writeable_reg, }; -enum ina2xx_ids { ina219, ina226 }; +enum ina2xx_ids { ina219, ina226, ina260 }; struct ina2xx_config { u16 config_default; bool has_alerts; /* chip supports alerts and limits */ + bool has_ishunt; /* chip has internal shunt resistor */ int calibration_value; int shunt_div; int bus_voltage_shift; @@ -157,6 +160,7 @@ static const struct ina2xx_config ina2xx_config[] = { .bus_voltage_lsb = 4000, .power_lsb_factor = 20, .has_alerts = false, + .has_ishunt = false, }, [ina226] = { .config_default = INA226_CONFIG_DEFAULT, @@ -166,6 +170,16 @@ static const struct ina2xx_config ina2xx_config[] = { .bus_voltage_lsb = 1250, .power_lsb_factor = 25, .has_alerts = true, + .has_ishunt = false, + }, + [ina260] = { + .config_default = INA260_CONFIG_DEFAULT, + .shunt_div = 400, + .bus_voltage_shift = 0, + .bus_voltage_lsb = 1250, + .power_lsb_factor = 8, + .has_alerts = true, + .has_ishunt = true, }, }; @@ -257,6 +271,15 @@ static int ina2xx_read_init(struct device *dev, int reg, long *val) unsigned int regval; int ret, retry; + if (data->config->has_ishunt) { + /* No calibration needed */ + ret = regmap_read(regmap, reg, ®val); + if (ret < 0) + return ret; + *val = ina2xx_get_value(data, reg, regval); + return 0; + } + for (retry = 5; retry; retry--) { ret = regmap_read(regmap, reg, ®val); if (ret < 0) @@ -686,7 +709,7 @@ static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type case hwmon_chip: switch (attr) { case hwmon_chip_update_interval: - if (chip == ina226) + if (chip == ina226 || chip == ina260) return 0644; break; default: @@ -795,7 +818,9 @@ static int ina2xx_init(struct device *dev, struct ina2xx_data *data) u32 shunt; int ret; - if (device_property_read_u32(dev, "shunt-resistor", &shunt) < 0) + if (data->config->has_ishunt) + shunt = INA260_RSHUNT; + else if (device_property_read_u32(dev, "shunt-resistor", &shunt) < 0) shunt = INA2XX_RSHUNT_DEFAULT; ret = ina2xx_set_shunt(data, shunt); @@ -815,6 +840,9 @@ static int ina2xx_init(struct device *dev, struct ina2xx_data *data) FIELD_PREP(INA226_ALERT_POLARITY, active_high)); } + if (data->config->has_ishunt) + return 0; + /* * Calibration register is set to the best value, which eliminates * truncation errors on calculating current register in hardware. @@ -860,7 +888,8 @@ static int ina2xx_probe(struct i2c_client *client) hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, &ina2xx_chip_info, - ina2xx_groups); + data->config->has_ishunt ? + NULL : ina2xx_groups); if (IS_ERR(hwmon_dev)) return PTR_ERR(hwmon_dev); @@ -876,6 +905,7 @@ static const struct i2c_device_id ina2xx_id[] = { { "ina226", ina226 }, { "ina230", ina226 }, { "ina231", ina226 }, + { "ina260", ina260 }, { } }; MODULE_DEVICE_TABLE(i2c, ina2xx_id); @@ -901,6 +931,10 @@ static const struct of_device_id __maybe_unused ina2xx_of_match[] = { .compatible = "ti,ina231", .data = (void *)ina226 }, + { + .compatible = "ti,ina260", + .data = (void *)ina260 + }, { }, }; MODULE_DEVICE_TABLE(of, ina2xx_of_match); -- 2.51.0 From ff140456b5fbf03cbd04277c21d4fcdc5974e97b Mon Sep 17 00:00:00 2001 From: Shen Lichuan Date: Thu, 19 Sep 2024 14:49:39 +0800 Subject: [PATCH 13/16] hwmon: (pmbus/mpq8785) Convert comma to semicolon To ensure code clarity and prevent potential errors, use ';' instead of ',' as a statement separator in the function mpq8785_identify. Signed-off-by: Shen Lichuan Message-ID: <20240919064939.3282-1-shenlichuan@vivo.com> Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/mpq8785.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/pmbus/mpq8785.c b/drivers/hwmon/pmbus/mpq8785.c index 7f87e117b49d..0d16491cd770 100644 --- a/drivers/hwmon/pmbus/mpq8785.c +++ b/drivers/hwmon/pmbus/mpq8785.c @@ -22,7 +22,7 @@ static int mpq8785_identify(struct i2c_client *client, break; case 1: case 2: - info->format[PSC_VOLTAGE_OUT] = direct, + info->format[PSC_VOLTAGE_OUT] = direct; info->m[PSC_VOLTAGE_OUT] = 64; info->b[PSC_VOLTAGE_OUT] = 0; info->R[PSC_VOLTAGE_OUT] = 1; -- 2.51.0 From 247a80fde14edc84feb8bae707e60a55993ee636 Mon Sep 17 00:00:00 2001 From: Farouk Bouabid Date: Fri, 6 Sep 2024 17:54:14 +0200 Subject: [PATCH 14/16] dt-bindings: hwmon: add support for ti,amc6821 Add dt-bindings for amc6821 intelligent temperature monitor and pulse-width modulation (PWM) fan controller. Reviewed-by: Rob Herring (Arm) Signed-off-by: Farouk Bouabid Message-ID: <20240906-dev-mule-i2c-mux-v8-3-dbd28a150e41@cherry.de> Signed-off-by: Guenter Roeck --- .../devicetree/bindings/hwmon/ti,amc6821.yaml | 86 +++++++++++++++++++ .../devicetree/bindings/trivial-devices.yaml | 2 - 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/hwmon/ti,amc6821.yaml diff --git a/Documentation/devicetree/bindings/hwmon/ti,amc6821.yaml b/Documentation/devicetree/bindings/hwmon/ti,amc6821.yaml new file mode 100644 index 000000000000..5d33f1a23d03 --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/ti,amc6821.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hwmon/ti,amc6821.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: AMC6821 Intelligent Temperature Monitor and PWM Fan Controller + +maintainers: + - Farouk Bouabid + - Quentin Schulz + +description: + Intelligent temperature monitor and pulse-width modulation (PWM) fan + controller. + +properties: + compatible: + oneOf: + - items: + - const: tsd,mule + - const: ti,amc6821 + - const: ti,amc6821 + + reg: + maxItems: 1 + + i2c-mux: + type: object + +required: + - compatible + - reg + +if: + properties: + compatible: + contains: + const: tsd,mule + +then: + required: + - i2c-mux + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + }; + }; + + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + fan@18 { + compatible = "tsd,mule", "ti,amc6821"; + reg = <0x18>; + + i2c-mux { + compatible = "tsd,mule-i2c-mux"; + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + + rtc@6f { + compatible = "isil,isl1208"; + reg = <0x6f>; + }; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 9bf0fb17a05e..b803581ba927 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -357,8 +357,6 @@ properties: - swir,mangoh-iotport-spi # Ambient Light Sensor with SMBUS/Two Wire Serial Interface - taos,tsl2550 - # Temperature Monitoring and Fan Control - - ti,amc6821 # Temperature and humidity sensor with i2c interface - ti,hdc1000 # Temperature and humidity sensor with i2c interface -- 2.51.0 From 8f38236de689afe1ebba6ff25676f0631818ef37 Mon Sep 17 00:00:00 2001 From: Farouk Bouabid Date: Fri, 6 Sep 2024 17:54:15 +0200 Subject: [PATCH 15/16] hwmon: (amc6821) add support for tsd,mule Theobroma Systems Mule is an MCU that emulates a set of I2C devices, among which is an amc6821 and other devices that are reachable through an I2C-mux. The devices on the mux can be selected by writing the appropriate device number to an I2C config register (amc6821: reg 0xff) Implement "tsd,mule" compatible to instantiate the I2C-mux platform device when probing the amc6821. Reviewed-by: Guenter Roeck Signed-off-by: Farouk Bouabid Message-ID: <20240906-dev-mule-i2c-mux-v8-4-dbd28a150e41@cherry.de> Signed-off-by: Guenter Roeck --- drivers/hwmon/amc6821.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index e86027f850c9..1e3c6acd8974 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -893,7 +894,6 @@ static bool amc6821_volatile_reg(struct device *dev, unsigned int reg) static const struct regmap_config amc6821_regmap_config = { .reg_bits = 8, .val_bits = 8, - .max_register = AMC6821_REG_CONF3, .volatile_reg = amc6821_volatile_reg, .cache_type = REGCACHE_MAPLE, }; @@ -920,6 +920,13 @@ static int amc6821_probe(struct i2c_client *client) if (err) return err; + if (of_device_is_compatible(dev->of_node, "tsd,mule")) { + err = devm_of_platform_populate(dev); + if (err) + return dev_err_probe(dev, err, + "Failed to create sub-devices\n"); + } + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, &amc6821_chip_info, amc6821_groups); @@ -937,6 +944,9 @@ static const struct of_device_id __maybe_unused amc6821_of_match[] = { { .compatible = "ti,amc6821", }, + { + .compatible = "tsd,mule", + }, { } }; -- 2.51.0 From edeed7b6666cd02bd7e370b47573d95bc9b0f51c Mon Sep 17 00:00:00 2001 From: "Everest K.C." Date: Mon, 30 Sep 2024 19:15:17 -0600 Subject: [PATCH 16/16] hwmon: (max31827) Fix spelling errors reported by codespell Below mentioned spelling errors reported by codesepll were fixed: respresents ==> represents signifcant ==> significant bandwitdh ==> bandwidth Signed-off-by: Everest K.C. Message-ID: <20241001011521.80982-1-everestkc@everestkc.com.np> Signed-off-by: Guenter Roeck --- Documentation/hwmon/max31827.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst index 9c11a9518c67..6cc5088b26b7 100644 --- a/Documentation/hwmon/max31827.rst +++ b/Documentation/hwmon/max31827.rst @@ -136,7 +136,7 @@ PEC Support When reading a register value, the PEC byte is computed and sent by the chip. -PEC on word data transaction respresents a signifcant increase in bandwitdh +PEC on word data transaction represents a significant increase in bandwidth usage (+33% for both write and reads) in normal conditions. Since this operation implies there will be an extra delay to each -- 2.51.0