Compare commits

..

No commits in common. "master" and "v7.4-rc1" have entirely different histories.

434 changed files with 4666 additions and 10967 deletions

View File

@ -233,10 +233,6 @@ Chuck Lever <cel@kernel.org> <chuck.lever@oracle.com>
Chuck Lever <cel@kernel.org> <cel@netapp.com>
Chuck Lever <cel@kernel.org> <cel@citi.umich.edu>
Claudiu Beznea <claudiu.beznea@tuxon.dev> <claudiu.beznea@microchip.com>
Clément Léger <clement.leger@linux.dev> <cleger@kalray.eu>
Clément Léger <clement.leger@linux.dev> <clement.leger@bootlin.com>
Clément Léger <clement.leger@linux.dev> <cleger@rivosinc.com>
Clément Léger <clement.leger@linux.dev> <cleger@meta.com>
Coiby Xu <coiby.xu@gmail.com> <coxu@redhat.com>
Colin Ian King <colin.i.king@gmail.com> <colin.king@canonical.com>
Corey Minyard <minyard@acm.org>

View File

@ -407,13 +407,6 @@ referenced kptr (by invoking bpf_kptr_xchg). If not, the verifier fails the
loading of the BPF program until no lingering references remain in all possible
explored states of the program.
A pointer to a struct in the arguments of a KF_ACQUIRE kfunc accepts only an
object of that type. The same applies to the argument that a KF_RELEASE kfunc
releases. For other arguments a kfunc also accepts memory of the program, if the
struct has only scalar members. A struct without members, struct __sk_buff and
struct xdp_md never accept memory. A KF_ACQUIRE kfunc which wants such memory
has to pair the pointer with a __sz argument.
2.5.2 KF_RET_NULL flag
----------------------

View File

@ -50,14 +50,6 @@ mount points. Each 9P export is seen by the client as a virtio device with an
associated "mount_tag" property. Available mount tags can be
seen by reading /sys/bus/virtio/drivers/9pnet_virtio/virtio<n>/mount_tag files.
For server accessible over vsock (VM sockets)::
mount -t 9p -o trans=vsock[,port=<port>] <CID> /mnt/9
where CID is the vsock Context ID of the remote endpoint (2 for host from
a guest VM, 3+ for guest VMs from the host). The port to connect to can be
specified with the port option (default: 564).
USBG Usage
==========
@ -125,8 +117,6 @@ Options
tcp specifying a normal TCP/IP connection
fd used passed file descriptors for connection
(see rfdno and wfdno)
vsock connect over VM sockets (vsock) using
CID as the mount source
virtio connect to the next virtio channel available
(from QEMU with trans_virtio module)
rdma connect to a specified RDMA channel
@ -238,7 +228,7 @@ Options
any
v9fs does single attach and performs all
operations as one user
client
clien
ACL based access check on the 9p client
side for access validation

View File

@ -731,8 +731,7 @@ When decoding an overlay file handle, the following steps are followed:
1. Find underlying layer by UUID and path type information.
2. Decode the underlying filesystem file handle to underlying dentry.
3. For a lower file handle, encode the decoded underlying inode again and
lookup that handle in index directory by name.
3. For a lower file handle, lookup the handle in index directory by name.
4. If a whiteout is found in index, return ESTALE. This represents an
overlay object that was deleted after its file handle was encoded.
5. For a non-directory, instantiate a disconnected overlay dentry from the

View File

@ -34,12 +34,6 @@ Usage notes
As these are USB HIDs, the driver can be loaded automatically by the kernel and
supports hot swapping.
The pump of the RYUJIN III also has a 4-pin cable for a motherboard fan header.
The cooler either hands the pump to its internal controller, which follows the
PWM of the header its 4-pin cable is plugged into, or runs it at the pump duty
set over USB. Writing pwm1 selects the duty set over USB. Writing pwm2 sets
only the internal fan duty and leaves the pump control as it is.
Sysfs entries
-------------

View File

@ -130,19 +130,8 @@ pages of ``struct page`` (page 1 to page 7) are tail pages.
The optimization is only applied when the size of the struct page is a power
of 2. In this case, all tail pages of the same order are identical. See
compound_head(). This allows us to remap the tail pages of the vmemmap to a
shared page. The head page is also remapped to a new page. This allows the
original vmemmap pages to be freed.
The shared page is mapped writable. A lockless get of a page reference can
read a non-zero refcount before the remap and attempt its atomic update
after it. The refcount of a tail page is zero, so the update fails without
changing the page. Nothing else may write to the shared page: it is shared
by all HugeTLB pages of the same size in the zone, and a stray write would
corrupt all of them.
HugeTLB pages whose vmemmap is optimized when the memmap is first set up at
boot keep a read-only mapping of the shared page. Nothing can do a lockless
get on them before they are handed to HugeTLB.
shared, read-only page. The head page is also remapped to a new page. This
allows the original vmemmap pages to be freed.
Here is how things look after remapping::

View File

@ -1040,21 +1040,17 @@ As described in :ref:`socketcan-receive-lists` the SocketCAN core uses several f
lists to deliver received CAN frames to CAN protocol modules. These
receive lists, their filters and the count of filter matches can be
checked in the appropriate receive list. All entries contain the
CAN network device, the filter (can_id/can_mask), the number of filter
matches, the inode number of the subscribing socket and the name of the
receive function. A sock_inode of 0 denotes a kernel internal subscriber
without a socket (e.g. CAN gateway or J1939). When the function name can
not be resolved (e.g. with CONFIG_KALLSYMS=n) "(unknown)" is printed::
device and a protocol module identifier::
foo@bar:~$ cat /proc/net/can/rcvlist_all
receive list 'rx_all':
(any: no entry)
device can_id can_mask matches sock_inode function
vcan0 000 00000000 0 63586 raw_rcv [can_raw]
(vcan1: no entry)
(vcan2: no entry)
(vcan3: no entry)
(vcan2: no entry)
(vcan1: no entry)
device can_id can_mask function userdata matches ident
vcan0 000 00000000 f88e6370 f6c6f400 0 raw
(any: no entry)
In this example an application requests any CAN traffic from vcan0::

View File

@ -27,20 +27,15 @@ SA Identification
=================
The struct is defined in ``include/uapi/linux/xfrm.h``. The SA is looked
up using ``xfrm_state_lookup_exact()`` with ``id.spi``, ``id.daddr``,
``id.proto``, ``id.family``, and an exact match against ``old_mark.v``
and ``old_mark.m``. Unlike the data path, which uses a masked
comparison, this requires the SA's mark and mask to equal ``old_mark``
exactly, so a broad-mask SA is never matched when a more specific one
was intended. If no such SA exists, ``-ESRCH`` is returned.
The layout is::
up using ``xfrm_state_lookup()`` with ``id.spi``,
``id.daddr``, ``id.proto``, ``id.family``, and
``old_mark.v & old_mark.m`` as the mark key::
struct xfrm_user_migrate_state {
struct xfrm_usersa_id id; /* spi, daddr, proto, family */
xfrm_address_t new_daddr;
xfrm_address_t new_saddr;
struct xfrm_mark old_mark; /* SA lookup key (exact v/m match) */
struct xfrm_mark old_mark; /* SA lookup: key = v & m */
struct xfrm_selector new_sel; /* new selector (see Flags) */
__u32 new_reqid;
__u32 flags; /* XFRM_MIGRATE_STATE_* */
@ -77,8 +72,8 @@ inherits the value from the existing SA (omit-to-inherit).
- Description
* - ``XFRMA_MARK``
- Mark on the migrated SA (``struct xfrm_mark``). Absent inherits
the mark of the existing SA. To use no mark on the new SA, send
``XFRMA_MARK`` with ``{0, 0}``.
``old_mark``. To use no mark on the new SA, send ``XFRMA_MARK``
with ``{0, 0}``.
* - ``XFRMA_ENCAP``
- UDP encapsulation template; only ``UDP_ENCAP_ESPINUDP`` is supported.
Set ``encap_type=0`` to remove encap.
@ -264,12 +259,8 @@ Attributes in the notification
Error Handling
==============
If the target SA tuple (new daddr, SPI, proto, new family, mark) is
already occupied, the operation returns ``-EEXIST`` before the migration
begins. "Occupied" includes wildcard shadowing: an existing SA with a
broader mask (e.g. mark 0/0) claims every mark value, so it blocks
migrating to any more specific mark at the same tuple, not just an
exact mark/mask duplicate.
If the target SA tuple (new daddr, SPI, proto, new family) is already
occupied, the operation returns ``-EEXIST`` before the migration begins.
The old SA remains intact and the operation is safe to retry after
resolving the conflict.

View File

@ -315,10 +315,6 @@ reproducer and against kernel selftests. If the bug is in a hardware driver,
the testing statement must include information about the HW on which the
fix was tested.
Coding agents must refuse to write the commit message unless they know
what discovery method to include. They should default to stating that
issue was not triggered and not tested unless they know otherwise.
Stable tree
~~~~~~~~~~~

View File

@ -6868,13 +6868,11 @@ R: Muchun Song <muchun.song@linux.dev>
L: cgroups@vger.kernel.org
L: linux-mm@kvack.org
S: Maintained
F: Documentation/admin-guide/cgroup-v1/memory.rst
F: include/linux/memcontrol.h
F: include/linux/page_counter.h
F: include/trace/events/memcg.h
F: mm/memcontrol.c
F: mm/memcontrol-v1.c
F: mm/memcontrol-v1.h
F: mm/memcontrol.c
F: mm/page_counter.c
F: samples/cgroup/*
F: tools/testing/selftests/cgroup/memcg_protection.m
@ -7838,7 +7836,7 @@ W: http://www.win.tue.nl/~aeb/linux/zip/zip-1.html
W: http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
DISKQUOTA
M: Jan Kara <jack@suse.cz>
M: Jan Kara <jack@suse.com>
S: Maintained
F: Documentation/filesystems/quota.rst
F: fs/quota/
@ -10109,7 +10107,7 @@ F: drivers/leds/leds-expresswire.c
F: include/linux/leds-expresswire.h
EXT2 FILE SYSTEM
M: Jan Kara <jack@suse.cz>
M: Jan Kara <jack@suse.com>
L: linux-ext4@vger.kernel.org
S: Maintained
F: Documentation/filesystems/ext2.rst
@ -12378,7 +12376,6 @@ R: David Hildenbrand <david@kernel.org>
L: linux-mm@kvack.org
S: Maintained
F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages
F: Documentation/admin-guide/cgroup-v1/hugetlb.rst
F: Documentation/admin-guide/mm/hugetlbpage.rst
F: Documentation/mm/hugetlbfs_reserv.rst
F: Documentation/mm/vmemmap_dedup.rst
@ -12390,7 +12387,6 @@ F: mm/hugetlb.c
F: mm/hugetlb_cgroup.c
F: mm/hugetlb_cma.c
F: mm/hugetlb_cma.h
F: mm/hugetlb_internal.h
F: mm/hugetlb_sysctl.c
F: mm/hugetlb_sysfs.c
F: mm/hugetlb_vmemmap.c
@ -12410,7 +12406,6 @@ M: Miaohe Lin <linmiaohe@huawei.com>
R: Naoya Horiguchi <nao.horiguchi@gmail.com>
L: linux-mm@kvack.org
S: Maintained
F: Documentation/ABI/testing/sysfs-memory-page-offline
F: include/linux/memory-failure.h
F: include/trace/events/memory-failure.h
F: mm/hwpoison-inject.c
@ -14075,16 +14070,6 @@ S: Maintained
F: io_uring/bpf-ops.*
F: io_uring/loop.*
IPC
M: Andrew Morton <akpm@linux-foundation.org>
R: Manfred Spraul <manfred@colorfullife.com>
R: Davidlohr Bueso <dave@stgolabs.net>
L: linux-kernel@vger.kernel.org
S: Maintained
F: ipc/
F: tools/testing/selftests/ipc/
F: tools/testing/selftests/mqueue/
IPMI SUBSYSTEM
M: Corey Minyard <corey@minyard.net>
L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers)
@ -14324,7 +14309,7 @@ F: include/uapi/linux/jffs2.h
JOURNALLING LAYER FOR BLOCK DEVICES (JBD2)
M: "Theodore Ts'o" <tytso@mit.edu>
M: Jan Kara <jack@suse.cz>
M: Jan Kara <jack@suse.com>
L: linux-ext4@vger.kernel.org
S: Maintained
F: fs/jbd2/
@ -17471,6 +17456,21 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
F: drivers/devfreq/tegra30-devfreq.c
MEMORY HOT(UN)PLUG
M: David Hildenbrand <david@kernel.org>
M: Oscar Salvador <osalvador@suse.de>
L: linux-mm@kvack.org
L: linux-cxl@vger.kernel.org
S: Maintained
F: Documentation/admin-guide/mm/memory-hotplug.rst
F: Documentation/core-api/memory-hotplug.rst
F: drivers/base/memory.c
F: include/linux/memory_hotplug.h
F: include/linux/memremap.h
F: mm/memremap.c
F: mm/memory_hotplug.c
F: tools/testing/selftests/memory-hotplug/
MEMORY MANAGEMENT
M: Andrew Morton <akpm@linux-foundation.org>
L: linux-mm@kvack.org
@ -17494,15 +17494,18 @@ F: mm/alloc_tag.c
F: tools/testing/selftests/alloc_tag/
MEMORY MANAGEMENT - BALLOON
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
L: linux-mm@kvack.org
L: virtualization@lists.linux.dev
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: include/linux/balloon.h
F: mm/balloon.c
MEMORY MANAGEMENT - CORE
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
R: Lorenzo Stoakes <ljs@kernel.org>
R: Liam R. Howlett <liam@infradead.org>
@ -17512,34 +17515,27 @@ R: Suren Baghdasaryan <surenb@google.com>
R: Michal Hocko <mhocko@suse.com>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: Documentation/admin-guide/sysctl/vm.rst
F: Documentation/core-api/gfp_mask-from-fs-io.rst
F: fs/proc/meminfo.c
F: include/linux/cacheflush.h
F: include/linux/folio_batch.h
F: include/linux/gfp.h
F: include/linux/gfp_types.h
F: include/linux/highmem-internal.h
F: include/linux/highmem.h
F: include/linux/leafops.h
F: include/linux/memory.h
F: include/linux/mm.h
F: include/linux/mm_*.h
F: include/linux/mmzone.h
F: include/linux/mmdebug.h
F: include/linux/mmu_notifier.h
F: include/linux/mmzone.h
F: include/linux/pagewalk.h
F: include/linux/pfn.h
F: include/linux/pgalloc.h
F: include/linux/pgtable.h
F: include/linux/ptdump.h
F: include/linux/sched/mm.h
F: include/linux/vm_event_item.h
F: include/linux/vmpressure.h
F: include/linux/vmstat.h
F: include/trace/events/mmflags.h
F: include/trace/events/pagemap.h
F: fs/proc/meminfo.c
F: kernel/fork.c
F: mm/Kconfig
F: mm/debug.c
@ -17558,7 +17554,6 @@ F: mm/ptdump.c
F: mm/util.c
F: mm/vmpressure.c
F: mm/vmstat.c
F: scripts/gdb/linux/mm.py
N: include\/linux\/page[-_][a-zA-Z]*
MEMORY MANAGEMENT - EXECMEM
@ -17570,14 +17565,15 @@ F: include/linux/execmem.h
F: mm/execmem.c
MEMORY MANAGEMENT - GUP (GET USER PAGES)
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
R: Jason Gunthorpe <jgg@nvidia.com>
R: John Hubbard <jhubbard@nvidia.com>
R: Peter Xu <peterx@redhat.com>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
F: Documentation/core-api/pin_user_pages.rst
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: mm/gup.c
F: mm/gup_test.c
F: mm/gup_test.h
@ -17586,12 +17582,14 @@ F: tools/testing/selftests/mm/gup.c
F: tools/testing/selftests/mm/gup_longterm.c
MEMORY MANAGEMENT - KSM (Kernel Samepage Merging)
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
R: Xu Xin <xu.xin@linux.dev>
R: Chengming Zhou <chengming.zhou@linux.dev>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: Documentation/ABI/testing/sysfs-kernel-mm-ksm
F: Documentation/admin-guide/mm/ksm.rst
F: Documentation/mm/ksm.rst
@ -17600,30 +17598,13 @@ F: include/trace/events/ksm.h
F: mm/ksm.c
F: mm/mm_slot.h
MEMORY MANAGEMENT - MEMORY HOT(UN)PLUG
M: David Hildenbrand <david@kernel.org>
M: Oscar Salvador <osalvador@suse.de>
L: linux-mm@kvack.org
L: linux-cxl@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
F: Documentation/ABI/testing/sysfs-devices-memory
F: Documentation/admin-guide/mm/memory-hotplug.rst
F: Documentation/core-api/memory-hotplug.rst
F: drivers/base/memory.c
F: include/linux/memory_hotplug.h
F: include/linux/memremap.h
F: mm/memory_hotplug.c
F: mm/memremap.c
F: tools/testing/selftests/memory-hotplug/
MEMORY MANAGEMENT - MEMORY MAP
M: Muchun Song <muchun.song@linux.dev>
M: Mike Rapoport <rppt@kernel.org>
M: David Hildenbrand <david@kernel.org>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git memmap
F: Documentation/mm/memory-model.rst
F: arch/*/include/asm/sparsemem.h
F: include/asm-generic/memory_model.h
@ -17655,6 +17636,7 @@ F: mm/vmscan.c
F: mm/workingset.c
MEMORY MANAGEMENT - MIGRATION
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
R: Zi Yan <ziy@nvidia.com>
R: Matthew Brost <matthew.brost@intel.com>
@ -17665,10 +17647,10 @@ R: Ying Huang <ying.huang@linux.alibaba.com>
R: Alistair Popple <apopple@nvidia.com>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: include/linux/migrate.h
F: include/linux/migrate_mode.h
F: include/trace/events/migrate.h
F: mm/migrate.c
F: mm/migrate_device.c
@ -17692,20 +17674,15 @@ F: Documentation/admin-guide/mm/
F: Documentation/core-api/memory-allocation.rst
F: Documentation/core-api/mm-api.rst
F: Documentation/mm/
F: fs/proc/page.c
F: include/linux/backing-dev-defs.h
F: include/linux/backing-dev.h
X: Documentation/admin-guide/mm/damon/
X: Documentation/mm/damon/
F: mm/char-mem.c
F: include/linux/cma.h
F: include/linux/dmapool.h
F: include/linux/ioremap.h
F: include/linux/kernel-page-flags.h
F: include/linux/page_idle.h
F: include/trace/events/cma.h
F: include/uapi/linux/kernel-page-flags.h
F: mm/backing-dev.c
F: mm/char-mem.c
F: mm/cma.c
F: mm/cma.h
F: mm/cma_debug.c
F: mm/cma_sysfs.c
F: mm/dmapool.c
@ -17718,11 +17695,7 @@ F: mm/page_idle.c
F: mm/pgalloc-track.h
F: mm/process_vm_access.c
F: tools/lib/mm/
F: tools/mm/
F: tools/testing/selftests/mm/
X: Documentation/ABI/testing/sysfs-kernel-mm-damon
X: Documentation/admin-guide/mm/damon/
X: Documentation/mm/damon/
MEMORY MANAGEMENT - NUMA MEMBLOCKS AND NUMA EMULATION
M: Andrew Morton <akpm@linux-foundation.org>
@ -17730,13 +17703,13 @@ M: Mike Rapoport <rppt@kernel.org>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git
F: include/linux/numa.h
F: include/linux/numa_memblks.h
F: mm/numa.c
F: mm/numa_emulation.c
F: mm/numa_memblks.c
MEMORY MANAGEMENT - NUMA PLACEMENT
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
M: Gregory Price <gourry@gourry.net>
R: Zi Yan <ziy@nvidia.com>
@ -17745,11 +17718,11 @@ R: Rakie Kim <rakie.kim@sk.com>
R: Ying Huang <ying.huang@linux.alibaba.com>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: Documentation/ABI/testing/sysfs-kernel-mm-memory-tiers
F: Documentation/ABI/testing/sysfs-kernel-mm-mempolicy
F: Documentation/ABI/testing/sysfs-kernel-mm-mempolicy-weighted-interleave
F: Documentation/admin-guide/numastat.rst
F: include/linux/memory-tiers.h
F: include/linux/mempolicy.h
F: include/uapi/linux/mempolicy.h
@ -17768,22 +17741,19 @@ F: include/uapi/linux/oom.h
F: mm/oom_kill.c
MEMORY MANAGEMENT - PAGE ALLOCATOR
M: Andrew Morton <akpm@linux-foundation.org>
M: Vlastimil Babka <vbabka@kernel.org>
M: Johannes Weiner <hannes@cmpxchg.org>
R: Suren Baghdasaryan <surenb@google.com>
R: Michal Hocko <mhocko@suse.com>
R: Brendan Jackman <brendan.jackman@linux.dev>
R: Johannes Weiner <hannes@cmpxchg.org>
R: Zi Yan <ziy@nvidia.com>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/page_alloc.git page_alloc/for-next
F: include/linux/compaction.h
F: include/linux/gfp.h
F: include/linux/page-isolation.h
F: include/linux/pageblock-flags.h
F: include/trace/events/compaction.h
F: include/trace/events/page_isolation.h
F: include/trace/events/page_ref.h
F: mm/compaction.c
F: mm/debug_page_alloc.c
F: mm/debug_page_ref.c
@ -17800,9 +17770,6 @@ F: mm/page_reporting.h
F: mm/show_mem.c
F: mm/shuffle.c
F: mm/shuffle.h
F: scripts/gdb/linux/page_owner.py
F: tools/mm/page_owner_filter.c
F: tools/mm/page_owner_sort.c
MEMORY MANAGEMENT - RECLAIM
M: Andrew Morton <akpm@linux-foundation.org>
@ -17814,11 +17781,11 @@ R: Shakeel Butt <shakeel.butt@linux.dev>
R: Lorenzo Stoakes <ljs@kernel.org>
L: linux-mm@kvack.org
S: Maintained
F: include/trace/events/vmscan.h
F: mm/vmscan.c
F: mm/workingset.c
MEMORY MANAGEMENT - RMAP (REVERSE MAPPING)
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
M: Lorenzo Stoakes <ljs@kernel.org>
R: Rik van Riel <riel@surriel.com>
@ -17829,7 +17796,6 @@ R: Jann Horn <jannh@google.com>
R: Lance Yang <lance.yang@linux.dev>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
F: include/linux/rmap.h
F: mm/interval_tree.c
F: mm/page_vma_mapped.c
@ -17844,54 +17810,6 @@ S: Maintained
F: include/linux/secretmem.h
F: mm/secretmem.c
MEMORY MANAGEMENT - SHARED MEMORY (SHMEM/TMPFS/MEMFD)
M: Hugh Dickins <hughd@google.com>
M: David Hildenbrand <david@kernel.org>
R: Baolin Wang <baolin.wang@linux.alibaba.com>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
F: Documentation/filesystems/tmpfs.rst
F: Documentation/mm/shmfs.rst
F: Documentation/userspace-api/mfd_noexec.rst
F: include/linux/memfd.h
F: include/linux/shmem_fs.h
F: include/uapi/linux/memfd.h
F: mm/memfd.c
F: mm/shmem.c
F: mm/shmem_quota.c
F: tools/testing/selftests/memfd/
F: tools/testing/selftests/tmpfs/
MEMORY MANAGEMENT - SLAB ALLOCATOR
M: Vlastimil Babka <vbabka@kernel.org>
M: Harry Yoo <harry@kernel.org>
R: Hao Li <hao.li@linux.dev>
R: Christoph Lameter <cl@gentwo.org>
R: David Rientjes <rientjes@google.com>
R: Roman Gushchin <roman.gushchin@linux.dev>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/slab.git slab/for-next
F: Documentation/ABI/testing/sysfs-kernel-slab
F: Documentation/admin-guide/mm/slab.rst
F: Documentation/mm/slab.rst
F: include/linux/mempool.h
F: include/linux/slab.h
F: include/trace/events/kmem.h
F: lib/tests/slub_kunit.c
F: mm/failslab.c
F: mm/mempool.c
F: mm/slab.h
F: mm/slab_common.c
F: mm/slub.c
F: scripts/gdb/linux/slab.py
F: tools/cgroup/memcg_slabinfo.py
F: tools/include/linux/slab.h
F: tools/lib/slab.c
F: tools/mm/slabinfo-gnuplot.sh
F: tools/mm/slabinfo.c
MEMORY MANAGEMENT - SWAP
M: Andrew Morton <akpm@linux-foundation.org>
M: Chris Li <chrisl@kernel.org>
@ -17911,13 +17829,14 @@ F: include/linux/swapfile.h
F: include/linux/swapops.h
F: mm/page_io.c
F: mm/swap.h
F: mm/swap_state.c
F: mm/swap_table.h
F: mm/swap_state.c
F: mm/swapfile.c
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
M: Andrew Morton <akpm@linux-foundation.org>
M: David Hildenbrand <david@kernel.org>
M: Zi Yan <ziy@nvidia.com>
R: Zi Yan <ziy@nvidia.com>
R: Baolin Wang <baolin.wang@linux.alibaba.com>
R: Liam R. Howlett <liam@infradead.org>
R: Nico Pache <nico.pache@linux.dev>
@ -17929,18 +17848,17 @@ R: Usama Arif <usama.arif@linux.dev>
R: Kiryl Shutsemau <kas@kernel.org>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/core.git for-next
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: Documentation/ABI/testing/sysfs-kernel-mm-transparent-hugepage
F: Documentation/admin-guide/mm/transhuge.rst
F: include/linux/huge_mm.h
F: include/linux/khugepaged.h
F: include/trace/events/huge_memory.h
F: include/trace/events/thp.h
F: mm/collapse.h
F: mm/huge_memory.c
F: mm/khugepaged.c
F: mm/mm_slot.h
F: tools/mm/thpmaps
F: tools/testing/selftests/mm/khugepaged.c
F: tools/testing/selftests/mm/split_huge_page_test.c
F: tools/testing/selftests/mm/transhuge-stress.c
@ -17984,16 +17902,10 @@ L: linux-mm@kvack.org
S: Maintained
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: Documentation/core-api/protection-keys.rst
F: Documentation/filesystems/mmap_prepare.rst
F: Documentation/userspace-api/mseal.rst
F: mm/char-mem.c
F: include/trace/events/mmap.h
F: fs/proc/task_mmu.c
F: fs/proc/task_nommu.c
F: include/linux/mman.h
F: include/linux/pkeys.h
F: include/trace/events/mmap.h
F: include/uapi/linux/mman.h
F: mm/char-mem.c
F: mm/mincore.c
F: mm/mlock.c
F: mm/mmap.c
@ -18831,7 +18743,6 @@ M: Peter Zijlstra <peterz@infradead.org>
L: linux-arch@vger.kernel.org
L: linux-mm@kvack.org
S: Maintained
F: Documentation/core-api/cachetlb.rst
F: arch/*/include/asm/tlb.h
F: include/asm-generic/tlb.h
F: include/trace/events/tlb.h
@ -21013,7 +20924,7 @@ S: Maintained
F: drivers/char/hw_random/optee-rng.c
OP-TEE RTC DRIVER
M: Clément Léger <clement.leger@linux.dev>
M: Clément Léger <clement.leger@bootlin.com>
L: linux-rtc@vger.kernel.org
S: Maintained
F: drivers/rtc/rtc-optee.c
@ -21942,7 +21853,6 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git
F: arch/*/include/asm/percpu.h
F: include/linux/percpu*.h
F: include/trace/events/percpu.h
F: lib/percpu*.c
F: mm/percpu*.c
F: mm/percpu-internal.h
@ -23913,7 +23823,7 @@ F: Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml
F: drivers/rtc/rtc-renesas-rtca3.c
RENESAS RZ/N1 A5PSW SWITCH DRIVER
M: Clément Léger <clement.leger@linux.dev>
M: Clément Léger <clement.leger@bootlin.com>
L: linux-renesas-soc@vger.kernel.org
L: netdev@vger.kernel.org
S: Maintained
@ -25669,7 +25579,6 @@ F: include/linux/shrinker.h
F: mm/list_lru.c
F: mm/shrinker.c
F: mm/shrinker_debug.c
F: tools/cgroup/memcg_shrinker.py
SH_VOU V4L2 OUTPUT DRIVER
L: linux-media@vger.kernel.org
@ -25891,6 +25800,34 @@ S: Maintained
F: Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml
F: drivers/nvmem/layouts/sl28vpd.c
SLAB ALLOCATOR
M: Vlastimil Babka <vbabka@kernel.org>
M: Harry Yoo <harry@kernel.org>
M: Andrew Morton <akpm@linux-foundation.org>
R: Hao Li <hao.li@linux.dev>
R: Christoph Lameter <cl@gentwo.org>
R: David Rientjes <rientjes@google.com>
R: Roman Gushchin <roman.gushchin@linux.dev>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/slab.git
F: Documentation/admin-guide/mm/slab.rst
F: Documentation/mm/slab.rst
F: include/linux/mempool.h
F: include/linux/slab.h
F: lib/tests/slub_kunit.c
F: mm/failslab.c
F: mm/mempool.c
F: mm/slab.h
F: mm/slab_common.c
F: mm/slub.c
F: scripts/gdb/linux/slab.py
F: tools/cgroup/memcg_slabinfo.py
F: tools/include/linux/slab.h
F: tools/lib/slab.c
F: tools/mm/slabinfo-gnuplot.sh
F: tools/mm/slabinfo.c
SLCAN CAN NETWORK DRIVER
M: Dario Binacchi <dario.binacchi@amarulasolutions.com>
L: linux-can@vger.kernel.org
@ -28308,6 +28245,17 @@ S: Maintained
F: Documentation/hwmon/tmp513.rst
F: drivers/hwmon/tmp513.c
TMPFS (SHMEM FILESYSTEM)
M: Hugh Dickins <hughd@google.com>
R: Baolin Wang <baolin.wang@linux.alibaba.com>
L: linux-mm@kvack.org
S: Maintained
F: include/linux/memfd.h
F: include/linux/shmem_fs.h
F: mm/memfd.c
F: mm/shmem.c
F: mm/shmem_quota.c
TOMOYO SECURITY MODULE
M: Kentaro Takeda <takedakn@nttdata.co.jp>
M: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
@ -28714,7 +28662,7 @@ F: arch/m68k/coldfire/
F: arch/m68k/include/asm/*_no.*
UDF FILESYSTEM
M: Jan Kara <jack@suse.cz>
M: Jan Kara <jack@suse.com>
S: Maintained
F: Documentation/filesystems/udf.rst
F: fs/udf/
@ -29662,12 +29610,9 @@ F: drivers/block/virtio_blk.c
F: drivers/crypto/virtio/
F: drivers/vdpa/
F: drivers/virtio/
F: include/linux/device-id/virtio.h
F: include/linux/vdpa.h
F: include/linux/virtio*.h
F: include/linux/vringh.h
F: include/uapi/linux/vdpa.h
F: include/uapi/linux/vduse.h
F: include/uapi/linux/virtio_*.h
F: net/vmw_vsock/virtio*
F: tools/virtio/
@ -29741,7 +29686,6 @@ F: drivers/vhost/
F: include/linux/sched/vhost_task.h
F: include/linux/vhost_iotlb.h
F: include/uapi/linux/vhost.h
F: include/uapi/linux/vhost_types.h
F: kernel/vhost_task.c
VIRTIO HOST (VHOST-SCSI)
@ -29935,11 +29879,9 @@ S: Maintained
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: include/linux/vmalloc.h
F: include/trace/events/vmalloc.h
F: lib/test_vmalloc.c
F: mm/vmalloc.c
F: mm/vmalloc.h
F: scripts/gdb/linux/vmalloc.py
F: lib/test_vmalloc.c
VME SUBSYSTEM
L: linux-kernel@vger.kernel.org

View File

@ -17,10 +17,16 @@ SYM_FUNC_START(arch_bpf_timed_may_goto)
str x7, [sp, #80]
/*
* The pointer to count and timestamp was passed in BPF_REG_AX (x9),
* pass it as the first argument in x0.
* Stack depth was passed in BPF_REG_AX (x9), add it to the BPF_FP
* (x25) to get the pointer to count and timestamp and pass it as the
* first argument in x0.
*
* Before generating the call to arch_bpf_timed_may_goto, the verifier
* generates a load instruction using FP, i.e. REG_AX = *(u64 *)(FP -
* stack_off_cnt), so BPF_REG_FP (x25) is always set up by the arm64
* jit in this case.
*/
mov x0, x9
add x0, x9, x25
bl bpf_check_timed_may_goto
/* BPF_REG_AX(x9) will be stored into count, so move return value to it. */
mov x9, x0

View File

@ -22,10 +22,14 @@ SYM_FUNC_START(arch_bpf_timed_may_goto)
st.d a4, sp, 48
/*
* BPF_REG_AX (t0) holds the pointer to the count and timestamp;
* pass it as the first argument in a0.
* BPF_REG_AX (t0) holds the offset passed in by the verifier;
* add it to BPF_REG_FP (s4) to get the pointer to the count and
* timestamp, then pass it as the first argument in a0.
*
* The verifier emits a load using FP right before this call,
* so BPF_REG_FP (s4) is always set up by the JIT in this case.
*/
move a0, t0
add.d a0, t0, s4
bl bpf_check_timed_may_goto
/* BPF_REG_AX (t0) will be stored into count, so move the return value to it. */
move t0, a0

View File

@ -35,7 +35,6 @@ DECLARE_EXPORT(__divsi3);
DECLARE_EXPORT(__umodsi3);
DECLARE_EXPORT(__modsi3);
DECLARE_EXPORT(__muldi3);
DECLARE_EXPORT(__mulsi3);
DECLARE_EXPORT(__ashrdi3);
DECLARE_EXPORT(__ashldi3);
DECLARE_EXPORT(__lshrdi3);

View File

@ -8,7 +8,7 @@
* arch_bpf_timed_may_goto() trampoline for powerpc64
*
* Custom BPF convention (verifier/JIT):
* - input: pointer to count and timestamp in BPF_REG_AX (r12)
* - input: stack offset in BPF_REG_AX (r12)
* - output: updated count in BPF_REG_AX (r12)
*
* Call bpf_check_timed_may_goto(ptr) with normal powerpc64 ABI:
@ -31,8 +31,11 @@ SYM_FUNC_START(arch_bpf_timed_may_goto)
std r7, 64(r1)
std r8, 72(r1)
/* r3 = BPF_REG_AX (r12) */
mr r3, r12
/*
* r3 = BPF_REG_FP + BPF_REG_AX
* BPF_REG_FP is r31; BPF_REG_AX is r12 (stack offset in bytes).
*/
add r3, r31, r12
bl CFUNC(bpf_check_timed_may_goto)
/* Put return value back into AX */

View File

@ -6,11 +6,13 @@
/*
* Trampoline for the BPF timed may_goto loop bound. Custom calling convention:
* - input: pointer to count and timestamp in BPF_REG_AX (t0)
* - input: stack offset in BPF_REG_AX (t0)
* - output: updated count in BPF_REG_AX (t0)
*
* Calls bpf_check_timed_may_goto(ptr) with the standard RISC-V ABI. BPF R0-R5
* (t6, a0-a4) and stack arguments 6-8 (a5-a7) are saved across the call.
* Calls bpf_check_timed_may_goto(ptr) with the standard RISC-V ABI, where
* ptr = BPF_REG_FP (s5) + BPF_REG_AX (t0). BPF R0-R5 (t6, a0-a4) and stack
* arguments 6-8 (a5-a7) are saved across the call; BPF_REG_FP (s5) is
* callee-saved and needs no saving.
*/
SYM_FUNC_START(arch_bpf_timed_may_goto)
@ -31,7 +33,7 @@ SYM_FUNC_START(arch_bpf_timed_may_goto)
REG_S a6, 7*SZREG(sp)
REG_S a7, 8*SZREG(sp)
mv a0, t0
add a0, t0, s5
call bpf_check_timed_may_goto
mv t0, a0

View File

@ -1005,17 +1005,6 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
(jit->prg - patch_brc) >> 1;
break;
}
if (insn_is_mov_percpu_addr(insn)) {
const u64 *percpu_offset = &get_lowcore()->percpu_offset;
if (dst_reg != src_reg)
/* lgr %dst,%src */
EMIT4(0xb9040000, dst_reg, src_reg);
/* ag %dst,percpu_offset */
EMIT6_DISP_LH(0xe3000000, 0x0008, dst_reg, REG_0, REG_0,
(unsigned long)percpu_offset);
break;
}
switch (insn->off) {
case 0: /* DST = SRC */
/* lgr %dst,%src */
@ -1877,9 +1866,9 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
if ((void *)func == arch_bpf_timed_may_goto) {
/*
* arch_bpf_timed_may_goto() has a special ABI: the
* parameter is in BPF_REG_AX; the return value is in
* BPF_REG_AX; and all GPRs except REG_W0, REG_W1, and
* BPF_REG_AX are callee-saved.
* parameters are in BPF_REG_AX and BPF_REG_10; the
* return value is in BPF_REG_AX; and all GPRs except
* REG_W0, REG_W1, and BPF_REG_AX are callee-saved.
*/
/* brasl %r0,func */
@ -2439,6 +2428,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
fp->jited_len = jit.size - cfi_get_offset();
if (!fp->is_func || extra_pass) {
for (int i = 0; i < fp->len; i++)
jit.addrs[i] -= cfi_get_offset();
bpf_prog_fill_jited_linfo(fp, jit.addrs + 1);
free_addrs:
kvfree(jit.addrs);
@ -3125,11 +3116,6 @@ bool bpf_jit_supports_timed_may_goto(void)
return true;
}
bool bpf_jit_supports_percpu_insn(void)
{
return true;
}
bool bpf_jit_inlines_helper_call(s32 imm)
{
switch (imm) {

View File

@ -21,9 +21,9 @@
SYM_FUNC_START(arch_bpf_timed_may_goto)
/*
* This function has a special ABI: the parameter is in %r12; the
* return value is in %r12; all GPRs except %r0, %r1, and %r12 are
* callee-saved; and the return address is in %r0.
* This function has a special ABI: the parameters are in %r12 and
* %r13; the return value is in %r12; all GPRs except %r0, %r1, and
* %r12 are callee-saved; and the return address is in %r0.
*/
stmg %r2,%r5,FRAME_OFF+R2_OFF(%r15)
stg %r14,FRAME_OFF+R14_OFF(%r15)
@ -33,7 +33,7 @@ SYM_FUNC_START(arch_bpf_timed_may_goto)
lay %r15,-FRAME_SIZE(%r15)
stg %r1,__SF_BACKCHAIN(%r15)
lgr %r2,%r12
lay %r2,0(%r12,%r13)
brasl %r14,bpf_check_timed_may_goto
lgr %r12,%r2

View File

@ -286,9 +286,9 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
RET
1:
/* See ftrace_jmp_set(), jmp to the trampoline */
btsq $63, %rax
jc 2f
testb $1, %al
jz 2f
andq $0xfffffffffffffffe, %rax
movq %rax, MCOUNT_REG_SIZE+8(%rsp)
restore_mcount_regs
/* Restore flags */

View File

@ -2359,16 +2359,6 @@ static struct kvm_mmu_page *kvm_mmu_find_shadow_page(struct kvm *kvm,
continue;
}
/*
* Note! Unlike fully direct MMUs, direct SPs in indirect MMUs
* can have an arbitrary number of parents, e.g if the guest is
* mapping a huge PTE at many points in its page tables.
*/
if (pte_list_count(&sp->parent_ptes) >= RMAP_RECYCLE_THRESHOLD) {
kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
break;
}
/* unsync and write-flooding only apply to indirect SPs. */
if (sp->role.direct)
goto out;

View File

@ -339,13 +339,6 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
gpa_t real_gpa;
gfn_t gfn;
/*
* KVM might sleep/resched when retrying the walk if the updating A/D
* fails because the gPTE changed between reading the gPTE and trying
* the CMPXHG to set A/D bits.
*/
might_sleep();
trace_kvm_mmu_pagetable_walk(addr, access);
retry_walk:
walker->level = w->cpu_role.base.level;
@ -488,10 +481,8 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
addr, write_fault);
if (unlikely(ret < 0))
goto error;
else if (ret) {
cond_resched();
else if (ret)
goto retry_walk;
}
}
return 1;

View File

@ -1889,21 +1889,6 @@ static void nested_copy_vmcb_cache_to_control(struct vmcb_control_area *dst,
/* 'clean' and 'hv_enlightenments' are not changed by KVM */
}
bool nested_svm_check_vmcb01_save(struct kvm_vcpu *vcpu,
struct vmcb_save_area *save)
{
struct vmcb_save_area_cached save_cached;
if (!(save->cr0 & X86_CR0_PG) ||
!(save->cr0 & X86_CR0_PE) ||
(save->rflags & X86_EFLAGS_VM) ||
((save->efer & EFER_LMA) && !(save->efer & EFER_LME)))
return false;
__nested_copy_vmcb_save_to_cache(&save_cached, save);
return nested_vmcb_check_save(vcpu, &save_cached, false);
}
static int svm_get_nested_state(struct kvm_vcpu *vcpu,
struct kvm_nested_state __user *user_kvm_nested_state,
u32 user_data_size)
@ -1983,6 +1968,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
&user_kvm_nested_state->data.svm[0];
struct vmcb_control_area *ctl;
struct vmcb_save_area *save;
struct vmcb_save_area_cached save_cached;
struct vmcb_ctrl_area_cached ctl_cached;
bool use_separate_l2_pat;
unsigned long cr0;
@ -2054,7 +2040,12 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
* KVM_GET_NESTED_STATE, and (b) it is not loaded at emulated
* #VMEXIT.
*/
if (!nested_svm_check_vmcb01_save(vcpu, save))
__nested_copy_vmcb_save_to_cache(&save_cached, save);
if (!(save->cr0 & X86_CR0_PG) ||
!(save->cr0 & X86_CR0_PE) ||
(save->rflags & X86_EFLAGS_VM) ||
((save->efer & EFER_LMA) && !(save->efer & EFER_LME)) ||
!nested_vmcb_check_save(vcpu, &save_cached, false))
goto out_free;
/*

View File

@ -5223,8 +5223,6 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
*/
svm_copy_vmrun_state(vcpu, &svm->vmcb01.ptr->save, m_save.map.hva + 0x400);
if (!nested_svm_check_vmcb01_save(vcpu, &svm->vmcb01.ptr->save))
return 1;
/*
* Enter the nested guest now

View File

@ -911,8 +911,6 @@ void nested_copy_vmcb_control_to_cache(struct vcpu_svm *svm,
void nested_copy_vmcb_save_to_cache(struct vcpu_svm *svm,
struct vmcb_save_area *save);
void nested_sync_control_from_vmcb02(struct vcpu_svm *svm);
bool nested_svm_check_vmcb01_save(struct kvm_vcpu *vcpu,
struct vmcb_save_area *save);
void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb);

View File

@ -136,8 +136,6 @@ static __always_inline int evmcs_field_offset(unsigned long field,
if (unlikely(index >= nr_evmcs_1_fields))
return -ENOENT;
index = array_index_nospec(index, nr_evmcs_1_fields);
evmcs_field = &vmcs_field_to_evmcs_1[index];
/*

View File

@ -5059,7 +5059,6 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu)
__func__, j, h.index, h.value);
goto vmabort;
}
break;
}
}

View File

@ -6558,12 +6558,10 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
} else if (vcpu->arch.complete_userspace_io) {
writeback = false;
r = 0;
} else if (r == EMULATION_RESTART) {
cond_resched();
} else if (r == EMULATION_RESTART)
goto restart;
} else {
else
r = 1;
}
writeback:
if (writeback) {
@ -9732,31 +9730,29 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
kvm_x86_call(update_exception_bitmap)(vcpu);
/*
* Unconditionally reset the MMU, even though super strictly speaking,
* a MMU reset is only necessary if and only one of the page role bits
* is changing. All of the CR0/CR4/EFER bits effectively get covered
* by checking CR0.PG=1, as CR0.WP and the paging-related bits in CR4
* and EFER are irrelevant if CR0.PG was '0'. Subtly, if the vCPU was
* in guest mode (L2) or SMM (although emulating INIT in SMM _should_
* be impossible), an MMU reset is also necessary as "guest mode" and
* "smm" are both encoded in the shadow page role. As a result, the
* only scenarios where an MMU reset is *not* needed is if the vCPU is
* in Real Mode or Unpaged Protected Mode, and micro-optimizing those
* paths are not worth the risk of running with a stale MMU context.
* On the standard CR0/CR4/EFER modification paths, there are several
* complex conditions determining whether the MMU has to be reset and/or
* which PCIDs have to be flushed. However, CR0.WP and the paging-related
* bits in CR4 and EFER are irrelevant if CR0.PG was '0'; and a reset+flush
* is needed anyway if CR0.PG was '1' (which can only happen for INIT, as
* CR0 will be '0' prior to RESET). So we only need to check CR0.PG here.
*/
kvm_mmu_reset_context(vcpu);
if (old_cr0 & X86_CR0_PG) {
kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
kvm_mmu_reset_context(vcpu);
}
/*
* Intel's SDM states that all TLB entries are flushed on INIT "as with
* a hardware reset", and AMD's APM states the TLBs are flushed on
* "External initialization of the processor". Flush the guest TLB for
* both RESET and INIT, regardless of vendor, even though both the SDM
* and APM contradict the above statements in other tables. There is
* no meaningful benefit in relying on the guest to flush the TLB, and
* a spurious TLB flush is benign and likely negligible from a
* performance perspective (especially for RESET).
* Intel's SDM states that all TLB entries are flushed on INIT. AMD's
* APM states the TLBs are untouched by INIT, but it also states that
* the TLBs are flushed on "External initialization of the processor."
* Flush the guest TLB regardless of vendor, there is no meaningful
* benefit in relying on the guest to flush the TLB immediately after
* INIT. A spurious TLB flush is benign and likely negligible from a
* performance perspective.
*/
kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
if (init_event)
kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_reset);

View File

@ -2626,13 +2626,8 @@ static int do_jit(struct bpf_verifier_env *env, struct bpf_prog *bpf_prog, int *
* Arg 6 goes into r9 register, not on stack.
*/
outgoing_rsp = out_stack_arg_cnt > 1 ? (out_stack_arg_cnt - 1) * 8 : 0;
/*
* bpf_throw() sees rsp of this frame as it is at a call. The callee-saved
* regs are above the outgoing args, or above r9, which is pushed around
* every call when the stack is private.
*/
if (bpf_prog->aux->exception_boundary)
bpf_prog->aux->stack_arg_sp_adjust = outgoing_rsp + (priv_frame_ptr ? 8 : 0);
bpf_prog->aux->stack_arg_sp_adjust = outgoing_rsp;
emit_sub_rsp(&prog, outgoing_rsp);
if (arena_vm_start)
@ -3441,6 +3436,18 @@ static int do_jit(struct bpf_verifier_env *env, struct bpf_prog *bpf_prog, int *
ip += emit_kfunc_arg_moves(fm, outgoing_arg_base -
outgoing_rsp, &prog);
}
if (func == (u8 *)arch_bpf_timed_may_goto) {
u32 fp = priv_frame_ptr ? X86_REG_R9 : BPF_REG_FP;
/*
* AX has the offset of count and timestamp
* in the stack. Turn it into a pointer.
* add r10, rbp or add r10, r9
*/
maybe_emit_mod(&prog, BPF_REG_AX, fp, true);
EMIT2(0x01, add_2reg(0xC0, BPF_REG_AX, fp));
ip += 3;
}
if (priv_frame_ptr) {
push_r9(&prog);
ip += 2;

View File

@ -25,7 +25,10 @@ SYM_FUNC_START(arch_bpf_timed_may_goto)
/* Save stack argument 6. */
pushq %r9
/* r10 has the pointer to count and timestamp. Pass it as first argument. */
/*
* r10 has the pointer to count and timestamp. JIT added the frame
* pointer to the offset. Pass it as first argument.
*/
movq %r10, %rdi
/* Emit call depth accounting for call below. */

View File

@ -1022,30 +1022,6 @@ static int init_vq(struct virtio_blk *vblk)
goto out;
for (i = 0; i < num_vqs; i++) {
unsigned int ring_size = virtqueue_get_vring_size(vqs[i]);
/*
* Each request consumes 2 extra descriptors (out_hdr and
* in_hdr) in addition to the data segments.
*
* At initial probe (!vblk->disk), each virtqueue must fit at
* least 1 data segment + 2 header descriptors (3).
* On resume/recovery (vblk->disk), each virtqueue must fit the
* existing queue_max_segments() + 2 header descriptors.
*/
unsigned int min_ring_size = 3;
if (vblk->disk)
min_ring_size = queue_max_segments(vblk->disk->queue) + 2;
if (ring_size < min_ring_size) {
dev_err(&vdev->dev,
"virtqueue %u ring size %u is smaller than minimum %u\n",
i, ring_size, min_ring_size);
vdev->config->del_vqs(vdev);
err = -EINVAL;
goto out;
}
spin_lock_init(&vblk->vqs[i].lock);
vblk->vqs[i].vq = vqs[i];
}
@ -1278,7 +1254,7 @@ static int virtblk_read_limits(struct virtio_blk *vblk,
u16 min_io_size;
u8 physical_block_exp, alignment_offset;
size_t max_dma_size;
int err, i;
int err;
/* We need to know how many segments before we allocate. */
err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SEG_MAX,
@ -1292,23 +1268,6 @@ static int virtblk_read_limits(struct virtio_blk *vblk,
/* Prevent integer overflows and honor max vq size */
sg_elems = min_t(u32, sg_elems, VIRTIO_BLK_MAX_SG_ELEMS - 2);
/*
* virtblk_add_req() uses separate outgoing and incoming header
* descriptors (out_hdr and in_hdr), consuming 2 extra descriptors
* per request in addition to the data segments.
*
* Per virtio specification (2.7.5.3.1), a driver MUST NOT create a
* descriptor chain longer than the Queue Size of the device.
*
* Clamp max_segments to (ring_size - 2) across all virtqueues so
* that a request never exceeds the ring size of any queue.
*/
for (i = 0; i < vblk->num_vqs; i++) {
u32 ring_size = virtqueue_get_vring_size(vblk->vqs[i].vq);
sg_elems = min_t(u32, sg_elems, ring_size - 2);
}
/* We can handle whatever the host told us to handle. */
lim->max_segments = sg_elems;
@ -1508,7 +1467,6 @@ static int virtblk_probe(struct virtio_device *vdev)
mutex_init(&vblk->vdev_mutex);
vblk->vdev = vdev;
vblk->disk = NULL;
INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
@ -1590,7 +1548,6 @@ static int virtblk_probe(struct virtio_device *vdev)
return 0;
out_cleanup_disk:
virtio_reset_device(vdev);
put_disk(vblk->disk);
out_free_tags:
blk_mq_free_tag_set(&vblk->tag_set);

View File

@ -318,10 +318,8 @@ struct xen_blkif {
unsigned int nr_ring_pages;
bool multi_ref;
/* All rings for this device. */
rwlock_t rings_lock;
struct xen_blkif_ring *rings;
unsigned int nr_rings;
unsigned long buffer_squeeze_end;
};

View File

@ -127,23 +127,14 @@ static void xen_update_blkif_status(struct xen_blkif *blkif)
return;
}
static int xen_blkif_alloc_rings(struct xen_blkif *blkif,
unsigned int nr_rings)
static int xen_blkif_alloc_rings(struct xen_blkif *blkif)
{
unsigned int r;
struct xen_blkif_ring *rings;
rings = kzalloc_objs(struct xen_blkif_ring, nr_rings);
if (!rings)
blkif->rings = kzalloc_objs(struct xen_blkif_ring, blkif->nr_rings);
if (!blkif->rings)
return -ENOMEM;
write_lock(&blkif->rings_lock);
blkif->rings = rings;
blkif->nr_rings = nr_rings;
write_unlock(&blkif->rings_lock);
for (r = 0; r < blkif->nr_rings; r++) {
struct xen_blkif_ring *ring = &blkif->rings[r];
@ -183,7 +174,6 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
blkif->domid = domid;
atomic_set(&blkif->refcnt, 1);
init_completion(&blkif->drain_complete);
rwlock_init(&blkif->rings_lock);
/*
* Because freeing back to the cache may be deferred, it is not
@ -278,7 +268,6 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
struct pending_req *req, *n;
unsigned int j, r;
bool busy = false;
struct xen_blkif_ring *rings;
for (r = 0; r < blkif->nr_rings; r++) {
struct xen_blkif_ring *ring = &blkif->rings[r];
@ -345,16 +334,10 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
* blkif->rings was allocated in connect_ring, so we should free it in
* here.
*/
write_lock(&blkif->rings_lock);
rings = blkif->rings;
kfree(blkif->rings);
blkif->rings = NULL;
blkif->nr_rings = 0;
write_unlock(&blkif->rings_lock);
kfree(rings);
return 0;
}
@ -402,7 +385,6 @@ void xen_blkif_interface_fini(void)
unsigned int i; \
unsigned long long result = 0; \
\
read_lock(&blkif->rings_lock); \
if (!blkif->rings) \
goto out; \
\
@ -413,7 +395,6 @@ void xen_blkif_interface_fini(void)
} \
\
out: \
read_unlock(&blkif->rings_lock); \
return sprintf(buf, format, result); \
} \
static DEVICE_ATTR(name, 0444, show_##name, NULL)
@ -1121,7 +1102,8 @@ static int connect_ring(struct backend_info *be)
requested_num_queues, xenblk_max_queues);
return -ENOSYS;
}
if (xen_blkif_alloc_rings(blkif, requested_num_queues))
blkif->nr_rings = requested_num_queues;
if (xen_blkif_alloc_rings(blkif))
return -ENOMEM;
pr_info("%s: using %d queues, protocol %d (%s) %s\n", dev->nodename,

View File

@ -1201,29 +1201,7 @@ static int btintel_download_firmware_payload(struct hci_dev *hdev,
err = -EINVAL;
while (fw_ptr - fw->data < fw->size) {
struct hci_command_hdr *cmd;
size_t remain = fw->size - (fw_ptr - fw->data);
/* Ensure the header fits before dereferencing */
if (frag_len + sizeof(*cmd) > remain) {
bt_dev_err(hdev,
"Firmware buffer overrun at header (frag_len %u, need %zu, remain %zu)",
frag_len, frag_len + sizeof(*cmd), remain);
err = -EINVAL;
goto done;
}
cmd = (void *)(fw_ptr + frag_len);
/* Ensure the full command (header + payload) fits before use */
if (frag_len + sizeof(*cmd) + cmd->plen > remain) {
bt_dev_err(hdev,
"Firmware buffer overrun at payload (frag_len %u, plen %u, need %zu, remain %zu)",
frag_len, cmd->plen,
frag_len + sizeof(*cmd) + cmd->plen, remain);
err = -EINVAL;
goto done;
}
struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);
frag_len += sizeof(*cmd) + cmd->plen;

View File

@ -7,7 +7,6 @@
#include <linux/usb.h>
#include <linux/iopoll.h>
#include <linux/overflow.h>
#include <linux/string.h>
#include <linux/unaligned.h>
#include <net/bluetooth/bluetooth.h>
@ -31,7 +30,7 @@
#define BTMTK_CBMCU_FLAG_ENABLE_PATCH 0xF1
/* It is for mt79xx iso data transmission setting */
#define MTK_ISO_THRESHOLD 342
#define MTK_ISO_THRESHOLD 264
struct btmtk_patch_header {
u8 datetime[16];
@ -1557,15 +1556,8 @@ static int btmtk_recv_isopkt(struct hci_dev *hdev, void *buffer, int count)
struct btmtk_data *btmtk_data = hci_get_priv(hdev);
struct sk_buff *skb;
unsigned long flags;
unsigned int iso_mtu;
int err = 0;
/* The controller reports the largest Data_Total_Length it will send in
* LE Read Buffer Size [v2]. Fall back to HCI_MAX_ISO_SIZE while that
* command has not completed yet.
*/
iso_mtu = hdev->iso_mtu ? hdev->iso_mtu : HCI_MAX_ISO_SIZE;
spin_lock_irqsave(&btmtk_data->isorxlock, flags);
skb = btmtk_data->isopkt_skb;
@ -1573,16 +1565,7 @@ static int btmtk_recv_isopkt(struct hci_dev *hdev, void *buffer, int count)
int len;
if (!skb) {
/* Drop the endpoint's zero-filled padding before
* allocating an skb for it; a zero Data_Total_Length
* check below would miss a padding remainder
* shorter than an ISO header.
*/
if (mem_is_zero(buffer, count))
break;
skb = bt_skb_alloc(HCI_ISO_HDR_SIZE + iso_mtu,
GFP_ATOMIC);
skb = bt_skb_alloc(HCI_MAX_ISO_SIZE, GFP_ATOMIC);
if (!skb) {
err = -ENOMEM;
break;
@ -1605,24 +1588,7 @@ static int btmtk_recv_isopkt(struct hci_dev *hdev, void *buffer, int count)
/* Complete ISO header */
hci_skb_expect(skb) = __le16_to_cpu(dlen);
if (!hci_skb_expect(skb)) {
/* Zero padding was ruled out above, so a
* zero Data_Total_Length here is invalid.
*/
kfree_skb(skb);
skb = NULL;
err = -EILSEQ;
break;
}
/* Reject a length the controller said it would never
* send. The skb_tailroom() test is kept because a
* fragment started before hdev->iso_mtu was populated
* sits in a smaller skb than iso_mtu now allows.
*/
if (hci_skb_expect(skb) > iso_mtu ||
skb_tailroom(skb) < hci_skb_expect(skb)) {
if (skb_tailroom(skb) < hci_skb_expect(skb)) {
kfree_skb(skb);
skb = NULL;
@ -1741,15 +1707,13 @@ static int btmtk_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
static int btmtk_usb_isointf_init(struct hci_dev *hdev)
{
struct btmtk_data *btmtk_data = hci_get_priv(hdev);
__le16 iso_param = cpu_to_le16(MTK_ISO_THRESHOLD);
u8 iso_param[2] = { 0x08, 0x01 };
struct sk_buff *skb;
int err;
spin_lock_init(&btmtk_data->isorxlock);
err = __set_mtk_intr_interface(hdev);
if (err < 0)
return err;
__set_mtk_intr_interface(hdev);
err = btmtk_submit_intr_urb(hdev, GFP_KERNEL);
if (err < 0) {
@ -1758,10 +1722,9 @@ static int btmtk_usb_isointf_init(struct hci_dev *hdev)
return err;
}
skb = __hci_cmd_sync(hdev, 0xfd98, sizeof(iso_param), &iso_param,
skb = __hci_cmd_sync(hdev, 0xfd98, sizeof(iso_param), iso_param,
HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
usb_kill_anchored_urbs(&btmtk_data->isopkt_anchor);
bt_dev_err(hdev, "Failed to apply iso setting (%ld)", PTR_ERR(skb));
return PTR_ERR(skb);
}

View File

@ -426,8 +426,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
tlv_nvm->data[0] |= 0x80;
/* UART Baud Rate */
if (soc_type == QCA_WCN3950 ||
soc_type >= QCA_WCN3991)
if (soc_type >= QCA_WCN3991)
tlv_nvm->data[1] = nvm_baud_rate;
else
tlv_nvm->data[2] = nvm_baud_rate;

View File

@ -190,7 +190,6 @@ static int probe_common(struct virtio_device *vdev)
err_find:
ida_free(&rng_index_ida, index);
err_ida:
vdev->priv = NULL;
kfree(vi);
return err;
}
@ -199,11 +198,6 @@ static void remove_common(struct virtio_device *vdev)
{
struct virtrng_info *vi = vdev->priv;
if (!vi) {
virtio_reset_device(vdev);
return;
}
vi->hwrng_removed = true;
vi->data_avail = 0;
vi->data_idx = 0;
@ -213,7 +207,6 @@ static void remove_common(struct virtio_device *vdev)
virtio_reset_device(vdev);
vdev->config->del_vqs(vdev);
ida_free(&rng_index_ida, vi->index);
vdev->priv = NULL;
kfree(vi);
}

View File

@ -341,7 +341,7 @@ static int coreboot_cfr_read_value(const struct coreboot_cfr_setting *setting,
int ret;
if (IS_ERR(efi_name))
return PTR_ERR(efi_name);
return PTR_ERR(no_free_ptr(efi_name));
ret = efivar_lock();
if (ret)

View File

@ -114,30 +114,6 @@ void coreboot_driver_unregister(struct coreboot_driver *driver)
}
EXPORT_SYMBOL(coreboot_driver_unregister);
/*
* Whether the memory of a CBMEM entry may be mapped: it must be exclusively
* System RAM, or exclusively Reserved memory, as CBMEM often is on x86, or
* memory that the kernel doesn't know about at all. coreboot leaves CBMEM out
* of the /memory node of the device tree that it passes to FIT payloads, e.g.
* on arm64, and only lists it in the memory reservation block.
*
* Anything else, such as no-map regions on arm64, which are IORESOURCE_MEM
* (see request_standard_resources() in arch/arm64/kernel/setup.c), must not
* be mapped.
*/
static bool cbmem_entry_is_mappable(const struct lb_cbmem_entry *entry)
{
resource_size_t start = entry->address;
size_t size = entry->entry_size;
return region_intersects(start, size, IORESOURCE_SYSTEM_RAM,
IORES_DESC_NONE) == REGION_INTERSECTS ||
region_intersects(start, size, IORESOURCE_MEM,
IORES_DESC_RESERVED) == REGION_INTERSECTS ||
region_intersects(start, size, IORESOURCE_MEM,
IORES_DESC_NONE) == REGION_DISJOINT;
}
static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_t len)
{
int i, ret;
@ -173,7 +149,23 @@ static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_
switch (device->entry.tag) {
case LB_TAG_CBMEM_ENTRY:
if (!cbmem_entry_is_mappable(&device->cbmem_entry)) {
/*
* Skip entries that are not exclusively System RAM or
* Reserved memory.
* On ARM64, no-map regions are filtered out as they are
* IORESOURCE_MEM (see request_standard_resources() in
* arch/arm64/kernel/setup.c).
* On x86, CBMEM often resides in standard reserved regions
* (IORES_DESC_RESERVED).
*/
if (region_intersects(device->cbmem_entry.address,
device->cbmem_entry.entry_size,
IORESOURCE_SYSTEM_RAM,
IORES_DESC_NONE) != REGION_INTERSECTS &&
region_intersects(device->cbmem_entry.address,
device->cbmem_entry.entry_size,
IORESOURCE_MEM,
IORES_DESC_RESERVED) != REGION_INTERSECTS) {
kfree(device);
continue;
}

View File

@ -30,6 +30,13 @@
#define POWER_METER_CAN_CAP (1 << 2)
#define POWER_METER_CAN_NOTIFY (1 << 3)
#define POWER_METER_IS_BATTERY (1 << 8)
#define UNKNOWN_HYSTERESIS 0xFFFFFFFF
/*
* ACPI integers can either be 32-bit or 64-bit wide, so
* we have to check for both values.
*/
#define UNKNOWN_POWER_32 U32_MAX
#define UNKNOWN_POWER_64 U64_MAX
#define METER_NOTIFY_CONFIG 0x80
#define METER_NOTIFY_TRIP 0x81
@ -47,15 +54,6 @@ static bool force_cap_on;
static DEFINE_MUTEX(acpi_notify_lock);
/*
* ACPI integers can either be 32-bit or 64-bit wide, so
* we have to check for both values.
*/
static bool acpi_power_meter_is_unknown(u64 val)
{
return val == U32_MAX || val == U64_MAX;
}
static int can_cap_in_hardware(void)
{
return force_cap_on || cap_in_hardware;
@ -181,10 +179,9 @@ static int update_meter(struct acpi_power_meter_resource *resource)
acpi_status status;
unsigned long local_jiffies = jiffies;
if (!acpi_power_meter_is_unknown(resource->caps.sampling_time) &&
time_before(local_jiffies, resource->sensors_last_updated +
if (time_before(local_jiffies, resource->sensors_last_updated +
msecs_to_jiffies(resource->caps.sampling_time)) &&
resource->sensors_valid)
resource->sensors_valid)
return 0;
status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM",
@ -380,30 +377,28 @@ static int set_avg_interval(struct acpi_power_meter_resource *resource,
return 0;
}
static bool get_power_alarm_state(struct acpi_power_meter_resource *resource)
static int get_power_alarm_state(struct acpi_power_meter_resource *resource,
long *val)
{
bool alarm = false;
int ret;
if (resource->caps.flags & POWER_METER_CAN_NOTIFY)
alarm = resource->power_alarm;
resource->power_alarm = false;
ret = update_meter(resource);
if (ret || acpi_power_meter_is_unknown(resource->power))
return alarm;
if (ret)
return ret;
/* need to update cap if not to support the notification. */
if (!(resource->caps.flags & POWER_METER_CAN_NOTIFY)) {
ret = update_cap(resource);
if (ret)
return false;
return ret;
resource->power_alarm = resource->power > resource->cap;
*val = resource->power_alarm;
} else {
*val = resource->power_alarm || resource->power > resource->cap;
resource->power_alarm = resource->power > resource->cap;
}
if (acpi_power_meter_is_unknown(resource->cap))
return alarm;
return alarm || resource->power > resource->cap;
return 0;
}
static umode_t power_meter_is_visible(const void *data,
@ -463,47 +458,37 @@ static int power_meter_read(struct device *dev, enum hwmon_sensor_types type,
ret = update_meter(res);
if (ret)
return ret;
if (acpi_power_meter_is_unknown(res->power))
if (res->power == UNKNOWN_POWER_32 || res->power == UNKNOWN_POWER_64)
return -ENODATA;
*val = res->power * 1000;
break;
case hwmon_power_average_interval_min:
if (acpi_power_meter_is_unknown(res->caps.min_avg_interval))
return -ENODATA;
*val = res->caps.min_avg_interval;
break;
case hwmon_power_average_interval_max:
if (acpi_power_meter_is_unknown(res->caps.max_avg_interval))
return -ENODATA;
*val = res->caps.max_avg_interval;
break;
case hwmon_power_average_interval:
ret = update_avg_interval(res);
if (ret)
return ret;
if (acpi_power_meter_is_unknown(res->avg_interval))
return -ENODATA;
*val = res->avg_interval;
*val = (res)->avg_interval;
break;
case hwmon_power_cap_min:
if (acpi_power_meter_is_unknown(res->caps.min_cap))
return -ENODATA;
*val = res->caps.min_cap * 1000;
break;
case hwmon_power_cap_max:
if (acpi_power_meter_is_unknown(res->caps.max_cap))
return -ENODATA;
*val = res->caps.max_cap * 1000;
break;
case hwmon_power_alarm:
*val = get_power_alarm_state(res);
ret = get_power_alarm_state(res, val);
if (ret)
return ret;
break;
case hwmon_power_cap:
ret = update_cap(res);
if (ret)
return ret;
if (acpi_power_meter_is_unknown(res->cap))
return -ENODATA;
*val = res->cap * 1000;
break;
default:
@ -599,8 +584,6 @@ static ssize_t power1_average_min_show(struct device *dev,
{
struct acpi_power_meter_resource *res = dev_get_drvdata(dev);
guard(mutex)(&res->lock);
if (res->trip[POWER_METER_TRIP_AVERAGE_MIN_IDX] < 0)
return sysfs_emit(buf, "unknown\n");
@ -613,8 +596,6 @@ static ssize_t power1_average_max_show(struct device *dev,
{
struct acpi_power_meter_resource *res = dev_get_drvdata(dev);
guard(mutex)(&res->lock);
if (res->trip[POWER_METER_TRIP_AVERAGE_MAX_IDX] < 0)
return sysfs_emit(buf, "unknown\n");
@ -627,9 +608,7 @@ static ssize_t power1_cap_hyst_show(struct device *dev,
{
struct acpi_power_meter_resource *res = dev_get_drvdata(dev);
guard(mutex)(&res->lock);
if (acpi_power_meter_is_unknown(res->caps.hysteresis))
if (res->caps.hysteresis == UNKNOWN_HYSTERESIS)
return sysfs_emit(buf, "unknown\n");
return sysfs_emit(buf, "%llu\n", res->caps.hysteresis * 1000);
@ -640,14 +619,8 @@ static ssize_t power1_accuracy_show(struct device *dev,
char *buf)
{
struct acpi_power_meter_resource *res = dev_get_drvdata(dev);
unsigned int acc;
unsigned int acc = res->caps.accuracy;
guard(mutex)(&res->lock);
if (acpi_power_meter_is_unknown(res->caps.accuracy))
return sysfs_emit(buf, "unknown\n");
acc = res->caps.accuracy;
return sysfs_emit(buf, "%u.%u%%\n", acc / 1000, acc % 1000);
}
@ -657,8 +630,6 @@ static ssize_t power1_is_battery_show(struct device *dev,
{
struct acpi_power_meter_resource *res = dev_get_drvdata(dev);
guard(mutex)(&res->lock);
return sysfs_emit(buf, "%u\n",
res->caps.flags & POWER_METER_IS_BATTERY ? 1 : 0);
}
@ -669,11 +640,6 @@ static ssize_t power1_model_number_show(struct device *dev,
{
struct acpi_power_meter_resource *res = dev_get_drvdata(dev);
guard(mutex)(&res->lock);
if (!res->model_number)
return -ENODATA;
return sysfs_emit(buf, "%s\n", res->model_number);
}
@ -683,11 +649,6 @@ static ssize_t power1_oem_info_show(struct device *dev,
{
struct acpi_power_meter_resource *res = dev_get_drvdata(dev);
guard(mutex)(&res->lock);
if (!res->oem_info)
return -ENODATA;
return sysfs_emit(buf, "%s\n", res->oem_info);
}
@ -697,11 +658,6 @@ static ssize_t power1_serial_number_show(struct device *dev,
{
struct acpi_power_meter_resource *res = dev_get_drvdata(dev);
guard(mutex)(&res->lock);
if (!res->serial_number)
return -ENODATA;
return sysfs_emit(buf, "%s\n", res->serial_number);
}
@ -1028,8 +984,6 @@ static int acpi_power_meter_resume(struct device *dev)
{
struct acpi_power_meter_resource *resource = dev_get_drvdata(dev);
guard(mutex)(&resource->lock);
free_capabilities(resource);
read_capabilities(resource);

View File

@ -19,7 +19,6 @@
#include <linux/hwmon.h>
#include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/unaligned.h>
@ -133,7 +132,6 @@ static u8 aquaero_secondary_ctrl_report[] = {
#define AQUAERO_FAN_CURRENT_OFFSET 0x06
#define AQUAERO_FAN_POWER_OFFSET 0x08
#define AQUAERO_FAN_SPEED_OFFSET 0x00
#define AQUAERO_MIN_STATUS_REPORT_SIZE (0x18B + AQUAERO_FAN_POWER_OFFSET + sizeof(u16))
static u16 aquaero_sensor_fan_offsets[] = { 0x167, 0x173, 0x17f, 0x18B };
/* Control report offsets for the Aquaero fan controllers */
@ -157,8 +155,6 @@ static u16 aquaero_ctrl_fan_offsets[] = { 0x20c, 0x220, 0x234, 0x248 };
#define D5NEXT_5V_VOLTAGE 0x39
#define D5NEXT_12V_VOLTAGE 0x37
#define D5NEXT_VIRTUAL_SENSORS_START 0x3f
#define D5NEXT_MIN_STATUS_REPORT_SIZE (D5NEXT_PUMP_OFFSET + AQC_FAN_SPEED_OFFSET + \
sizeof(u16))
static u16 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET };
/* Control report offsets for the D5 Next pump */
@ -183,14 +179,11 @@ static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 }; /* Pump and fan speed (fr
#define AQUASTREAMULT_FAN_CURRENT_OFFSET 0x00
#define AQUASTREAMULT_FAN_POWER_OFFSET 0x04
#define AQUASTREAMULT_FAN_SPEED_OFFSET 0x06
#define AQUASTREAMULT_MIN_STATUS_REPORT_SIZE (AQUASTREAMULT_PRESSURE_OFFSET + sizeof(u16))
static u16 aquastreamult_sensor_fan_offsets[] = { AQUASTREAMULT_FAN_OFFSET };
/* Spec and sensor report offset for the Farbwerk RGB controller */
#define FARBWERK_NUM_SENSORS 4
#define FARBWERK_SENSOR_START 0x2f
#define FARBWERK_MIN_STATUS_REPORT_SIZE (FARBWERK_SENSOR_START + \
FARBWERK_NUM_SENSORS * AQC_SENSOR_SIZE)
/* Specs of the Farbwerk 360 RGB controller */
#define FARBWERK360_NUM_SENSORS 4
@ -200,8 +193,6 @@ static u16 aquastreamult_sensor_fan_offsets[] = { AQUASTREAMULT_FAN_OFFSET };
/* Sensor report offsets for the Farbwerk 360 */
#define FARBWERK360_SENSOR_START 0x32
#define FARBWERK360_VIRTUAL_SENSORS_START 0x3a
#define FARBWERK360_MIN_STATUS_REPORT_SIZE (FARBWERK360_VIRTUAL_SENSORS_START + \
FARBWERK360_NUM_VIRTUAL_SENSORS * AQC_SENSOR_SIZE)
/* Control report offsets for the Farbwerk 360 */
#define FARBWERK360_TEMP_CTRL_OFFSET 0x8
@ -218,7 +209,6 @@ static u16 aquastreamult_sensor_fan_offsets[] = { AQUASTREAMULT_FAN_OFFSET };
#define OCTO_SENSOR_START 0x3D
#define OCTO_VIRTUAL_SENSORS_START 0x45
#define OCTO_FLOW_SENSOR_OFFSET 0x7B
#define OCTO_MIN_STATUS_REPORT_SIZE (0xD8 + AQC_FAN_SPEED_OFFSET + sizeof(u16))
static u16 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 };
/* Control report offsets for the Octo */
@ -239,7 +229,6 @@ static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0
#define QUADRO_SENSOR_START 0x34
#define QUADRO_VIRTUAL_SENSORS_START 0x3c
#define QUADRO_FLOW_SENSOR_OFFSET 0x6e
#define QUADRO_MIN_STATUS_REPORT_SIZE (0x97 + AQC_FAN_SPEED_OFFSET + sizeof(u16))
static u16 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 };
/* Control report offsets for the Quadro */
@ -259,7 +248,6 @@ static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; /* Fan speed
#define HIGHFLOWNEXT_CONDUCTIVITY 95
#define HIGHFLOWNEXT_5V_VOLTAGE 97
#define HIGHFLOWNEXT_5V_VOLTAGE_USB 99
#define HIGHFLOWNEXT_MIN_STATUS_REPORT_SIZE (HIGHFLOWNEXT_5V_VOLTAGE_USB + sizeof(u16))
/* Specs of the Leakshield */
#define LEAKSHIELD_NUM_SENSORS 2
@ -275,7 +263,6 @@ static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; /* Fan speed
#define LEAKSHIELD_FLOW_IN 111
#define LEAKSHIELD_RESERVOIR_VOLUME 313
#define LEAKSHIELD_RESERVOIR_FILLED 311
#define LEAKSHIELD_MIN_STATUS_REPORT_SIZE (LEAKSHIELD_RESERVOIR_VOLUME + sizeof(u16))
/* Specs of the Aquastream XT pump */
#define AQUASTREAMXT_SERIAL_START 0x3a
@ -567,7 +554,6 @@ struct aqc_data {
const char *name;
int status_report_id; /* Used for legacy devices, report is stored in buffer */
u16 min_report_size;
int ctrl_report_id;
int secondary_ctrl_report_id;
int secondary_ctrl_report_size;
@ -613,9 +599,9 @@ struct aqc_data {
u32 speed_input_min[1];
u32 speed_input_target[1];
u32 speed_input_max[1];
long power_input[8];
u32 power_input[8];
u16 voltage_input[8];
u32 current_input[8];
u16 current_input[8];
/* Label values */
const char *const *temp_label;
@ -990,7 +976,7 @@ static int aqc_legacy_read(struct aqc_data *priv)
/* Calculation derived from linear regression */
sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_PUMP_CURR_OFFSET);
priv->current_input[0] = max(DIV_ROUND_CLOSEST(sensor_value * 176, 100) - 52, 0);
priv->current_input[0] = DIV_ROUND_CLOSEST(sensor_value * 176, 100) - 52;
sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_PUMP_VOLTAGE_OFFSET);
priv->voltage_input[0] = DIV_ROUND_CLOSEST(sensor_value * 1000, 61);
@ -1020,7 +1006,6 @@ static int aqc_legacy_read(struct aqc_data *priv)
static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
int channel, long *val)
{
long power;
int ret;
struct aqc_data *priv = dev_get_drvdata(dev);
@ -1085,10 +1070,7 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
}
break;
case hwmon_power:
power = READ_ONCE(priv->power_input[channel]);
if (power == -ENODATA)
return -ENODATA;
*val = power;
*val = priv->power_input[channel];
break;
case hwmon_pwm:
switch (priv->kind) {
@ -1351,8 +1333,6 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
return 0;
priv = hid_get_drvdata(hdev);
if (!priv->min_report_size || size < priv->min_report_size)
return 0;
/* Info provided with every report */
priv->serial_number[0] = get_unaligned_be16(data + priv->serial_number_start_offset);
@ -1388,9 +1368,9 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
priv->speed_input[i] =
get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
priv->fan_structure->speed);
WRITE_ONCE(priv->power_input[i],
get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
priv->fan_structure->power) * 10000);
priv->power_input[i] =
get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
priv->fan_structure->power) * 10000;
priv->voltage_input[i] =
get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
priv->fan_structure->voltage) * 10;
@ -1430,8 +1410,7 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
priv->speed_input[2] = get_unaligned_be16(data + AQUASTREAMULT_PRESSURE_OFFSET);
priv->speed_input[3] = get_unaligned_be16(data + AQUASTREAMULT_FLOW_SENSOR_OFFSET);
WRITE_ONCE(priv->power_input[1],
get_unaligned_be16(data + AQUASTREAMULT_PUMP_POWER) * 10000);
priv->power_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_POWER) * 10000;
priv->voltage_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_VOLTAGE) * 10;
@ -1444,11 +1423,10 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
case highflownext:
/* If external temp sensor is not connected, its power reading is also N/A */
if (priv->temp_input[1] == -ENODATA)
WRITE_ONCE(priv->power_input[0], -ENODATA);
priv->power_input[0] = -ENODATA;
else
WRITE_ONCE(priv->power_input[0],
min_t(u64, get_unaligned_be16(data + HIGHFLOWNEXT_POWER) *
1000000ULL, LONG_MAX));
priv->power_input[0] =
get_unaligned_be16(data + HIGHFLOWNEXT_POWER) * 1000000;
priv->voltage_input[0] = get_unaligned_be16(data + HIGHFLOWNEXT_5V_VOLTAGE) * 10;
priv->voltage_input[1] =
@ -1540,7 +1518,6 @@ static void aqc_debugfs_init(struct aqc_data *priv)
static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
struct aqc_data *priv;
u16 min_report_size = 0;
int ret;
priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
@ -1577,7 +1554,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
* they present. The two other devices have the type of the second element in
* their respective collections set to 1, while the real device has it set to 0.
*/
if (hdev->maxcollection < 2 || hdev->collection[1].type != 0) {
if (hdev->collection[1].type != 0) {
ret = -ENODEV;
goto fail_and_close;
}
@ -1608,7 +1585,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_fan_power;
priv->voltage_label = label_fan_voltage;
priv->current_label = label_fan_current;
min_report_size = AQUAERO_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_D5NEXT:
priv->kind = d5next;
@ -1634,7 +1610,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_d5next_power;
priv->voltage_label = label_d5next_voltages;
priv->current_label = label_d5next_current;
min_report_size = D5NEXT_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_FARBWERK:
priv->kind = farbwerk;
@ -1645,7 +1620,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_sensor_start_offset = FARBWERK_SENSOR_START;
priv->temp_label = label_temp_sensors;
min_report_size = FARBWERK_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_FARBWERK360:
priv->kind = farbwerk360;
@ -1662,7 +1636,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_label = label_temp_sensors;
priv->virtual_temp_label = label_virtual_temp_sensors;
min_report_size = FARBWERK360_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_OCTO:
priv->kind = octo;
@ -1692,7 +1665,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_fan_power;
priv->voltage_label = label_fan_voltage;
priv->current_label = label_fan_current;
min_report_size = OCTO_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_QUADRO:
priv->kind = quadro;
@ -1722,7 +1694,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_fan_power;
priv->voltage_label = label_fan_voltage;
priv->current_label = label_fan_current;
min_report_size = QUADRO_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_HIGHFLOWNEXT:
priv->kind = highflownext;
@ -1740,7 +1711,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->speed_label = label_highflownext_fan_speed;
priv->power_label = label_highflownext_power;
priv->voltage_label = label_highflownext_voltage;
min_report_size = HIGHFLOWNEXT_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_LEAKSHIELD:
/*
@ -1760,7 +1730,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_label = label_leakshield_temp_sensors;
priv->speed_label = label_leakshield_fan_speed;
min_report_size = LEAKSHIELD_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_AQUASTREAMXT:
priv->kind = aquastreamxt;
@ -1791,7 +1760,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_aquastreamult_power;
priv->voltage_label = label_aquastreamult_voltages;
priv->current_label = label_aquastreamult_current;
min_report_size = AQUASTREAMULT_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_POWERADJUST3:
priv->kind = poweradjust3;
@ -1865,8 +1833,6 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
break;
}
priv->min_report_size = min_report_size;
if (priv->buffer_size != 0) {
priv->checksum_start = 0x01;
priv->checksum_length = priv->buffer_size - 3;

View File

@ -50,7 +50,6 @@ static const struct rog_ryujin_device_info rog_ryujin_iii_info = {
#define MAX_REPORT_LENGTH 65
/* Cooler duty report offsets */
#define RYUJIN_PUMP_SOURCE 3
#define RYUJIN_PUMP_DUTY 4
#define RYUJIN_INTERNAL_FAN_DUTY 5
@ -71,15 +70,10 @@ static const u8 get_cooler_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x9A };
static const u8 get_controller_speed_cmd[] = { RYUJIN_CMD_PREFIX, 0xA0 };
static const u8 get_controller_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0xA1 };
#define RYUJIN_SET_COOLER_CHANNEL_OFFSET 2
#define RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET 3
#define RYUJIN_SET_COOLER_FAN_DUTY_OFFSET 4
static const u8 set_cooler_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x1A, 0x00, 0x00, 0x00 };
/* Pump control sources in the set cooler duty command and the cooler duty report */
#define RYUJIN_SOURCE_HEADER 0
#define RYUJIN_SOURCE_USB 1
#define RYUJIN_SET_CONTROLLER_FAN_DUTY_OFFSET 4
static const u8 set_controller_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x21, 0x00, 0x00, 0x00 };
@ -123,7 +117,6 @@ struct rog_ryujin_data {
s32 temp_input[1];
u16 speed_input[6]; /* Pump, internal fan and four controller fan speeds in RPM */
u8 duty_input[3]; /* Pump, internal fan and controller fan duty in PWM */
u8 pump_source; /* Pump control source from the cooler duty report */
u8 *buffer;
unsigned long updated; /* jiffies */
@ -207,23 +200,16 @@ static int rog_ryujin_execute_cmd(struct rog_ryujin_data *priv, const u8 *cmd, i
/* Send command for getting data */
ret = rog_ryujin_write_expanded(priv, cmd, cmd_length);
if (ret < 0)
goto out_complete;
return ret;
ret = wait_for_completion_interruptible_timeout(status_completion,
msecs_to_jiffies(STATUS_VALIDITY));
if (ret == 0)
ret = -ETIMEDOUT;
if (ret < 0)
goto out_complete;
return -ETIMEDOUT;
else if (ret < 0)
return ret;
return 0;
out_complete:
spin_lock_irqsave(&priv->status_report_request_lock, flags);
if (!completion_done(status_completion))
complete_all(status_completion);
spin_unlock_irqrestore(&priv->status_report_request_lock, flags);
return ret;
}
static int rog_ryujin_get_status(struct rog_ryujin_data *priv)
@ -320,44 +306,6 @@ static int rog_ryujin_read_string(struct device *dev, enum hwmon_sensor_types ty
return 0;
}
/*
* On devices with a non-zero duty_channel (the RYUJIN III), the channel byte of
* the set cooler duty command selects the pump control source.
* RYUJIN_SOURCE_HEADER hands the pump to its internal controller, which follows
* the PWM of the header its 4-pin cable is plugged into. RYUJIN_SOURCE_USB
* makes the pump follow the pump duty in the command. The cooler duty report
* returns the current source.
*
* A fan duty write sends the reported source back, so that it leaves the pump
* control source as it is. A pump duty write selects USB. The cooler does not
* pass on a pump duty equal to the one it reports, and after power-on it
* reports 40% while a pump handed over at that duty runs at full speed. So
* when a pump duty write asks for the reported duty, write a duty 1% away
* first.
*/
static int rog_ryujin_select_pump_source(struct rog_ryujin_data *priv, u8 *set_cmd,
int channel)
{
u8 duty = set_cmd[RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET];
int ret;
if (channel == 1) {
set_cmd[RYUJIN_SET_COOLER_CHANNEL_OFFSET] = priv->pump_source;
return 0;
}
set_cmd[RYUJIN_SET_COOLER_CHANNEL_OFFSET] = RYUJIN_SOURCE_USB;
if (duty != rog_ryujin_pwm_to_percent(priv->duty_input[0]))
return 0;
set_cmd[RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET] = duty < 100 ? duty + 1 : duty - 1;
ret = rog_ryujin_execute_cmd(priv, set_cmd, SET_CMD_LENGTH, &priv->cooler_duty_set);
set_cmd[RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET] = duty;
return ret;
}
static int rog_ryujin_write_fixed_duty(struct rog_ryujin_data *priv, int channel, int val)
{
u8 set_cmd[SET_CMD_LENGTH];
@ -375,7 +323,7 @@ static int rog_ryujin_write_fixed_duty(struct rog_ryujin_data *priv, int channel
return ret;
memcpy(set_cmd, set_cooler_duty_cmd, SET_CMD_LENGTH);
set_cmd[RYUJIN_SET_COOLER_CHANNEL_OFFSET] = priv->info->duty_channel;
set_cmd[2] = priv->info->duty_channel;
/* Cooler duties are set as 0-100% */
val = rog_ryujin_pwm_to_percent(val);
@ -392,12 +340,6 @@ static int rog_ryujin_write_fixed_duty(struct rog_ryujin_data *priv, int channel
set_cmd[RYUJIN_SET_COOLER_FAN_DUTY_OFFSET] = val;
}
if (priv->info->duty_channel) {
ret = rog_ryujin_select_pump_source(priv, set_cmd, channel);
if (ret < 0)
return ret;
}
return rog_ryujin_execute_cmd(priv, set_cmd, SET_CMD_LENGTH, &priv->cooler_duty_set);
} else {
/*
@ -540,7 +482,6 @@ static int rog_ryujin_raw_event(struct hid_device *hdev, struct hid_report *repo
goto unlock;
}
read_cooler_duty:
priv->pump_source = data[RYUJIN_PUMP_SOURCE];
priv->duty_input[0] = rog_ryujin_percent_to_pwm(data[RYUJIN_PUMP_DUTY]);
priv->duty_input[1] = rog_ryujin_percent_to_pwm(data[RYUJIN_INTERNAL_FAN_DUTY]);
@ -637,18 +578,6 @@ static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id
init_completion(&priv->cooler_duty_set);
init_completion(&priv->controller_duty_set);
/*
* Start completions in the completed state so rog_ryujin_raw_event()
* only sees !completion_done() while rog_ryujin_execute_cmd() is
* awaiting a response.
*/
complete_all(&priv->cooler_status_received);
complete_all(&priv->controller_status_received);
complete_all(&priv->cooler_duty_received);
complete_all(&priv->controller_duty_received);
complete_all(&priv->cooler_duty_set);
complete_all(&priv->controller_duty_set);
priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "rog_ryujin",
priv, &rog_ryujin_chip_info, NULL);
if (IS_ERR(priv->hwmon_dev)) {

View File

@ -164,7 +164,6 @@ struct asus_wmi_wmi_info {
struct asus_wmi_sensors {
struct asus_wmi_wmi_info wmi;
struct hwmon_chip_info chip_info;
/* lock access to internal cache */
struct mutex lock;
};
@ -497,6 +496,11 @@ static const struct hwmon_ops asus_wmi_hwmon_ops = {
.read_string = asus_wmi_hwmon_read_string,
};
static struct hwmon_chip_info asus_wmi_chip_info = {
.ops = &asus_wmi_hwmon_ops,
.info = NULL,
};
static int asus_wmi_configure_sensor_setup(struct device *dev,
struct asus_wmi_sensors *sensor_data)
{
@ -504,7 +508,7 @@ static int asus_wmi_configure_sensor_setup(struct device *dev,
struct hwmon_channel_info *asus_wmi_hwmon_chan;
int nr_count[hwmon_max] = {}, nr_types = 0;
struct asus_wmi_sensor_info *temp_sensor;
struct hwmon_chip_info *chip_info;
const struct hwmon_chip_info *chip_info;
enum hwmon_sensor_types type;
struct device *hwdev;
int i, idx;
@ -545,9 +549,8 @@ static int asus_wmi_configure_sensor_setup(struct device *dev,
if (!ptr_asus_wmi_ci)
return -ENOMEM;
chip_info = &sensor_data->chip_info;
chip_info->ops = &asus_wmi_hwmon_ops;
chip_info->info = ptr_asus_wmi_ci;
asus_wmi_chip_info.info = ptr_asus_wmi_ci;
chip_info = &asus_wmi_chip_info;
sensor_data->wmi.info_by_id = devm_kcalloc(dev, sensor_data->wmi.sensor_count,
sizeof(*sensor_data->wmi.info_by_id),

View File

@ -20,9 +20,7 @@
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/unaligned.h>
#include <linux/regulator/consumer.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
@ -92,9 +90,6 @@ struct cc2_data {
int irq_low;
int irq_high;
bool process_irqs;
/* protects process_irqs and the alarm indicators */
struct mutex irq_lock;
bool regulator_enabled;
};
/* %RH as a per cent mille from a register value */
@ -123,33 +118,20 @@ static int cc2_enable(struct cc2_data *data)
{
int ret;
if (data->irq_ready > 0) {
scoped_guard(mutex, &data->irq_lock)
data->process_irqs = false;
synchronize_irq(data->irq_ready);
scoped_guard(mutex, &data->irq_lock)
reinit_completion(&data->complete);
}
/* exclusive regulator, check in case a disable failed */
if (data->regulator_enabled) {
scoped_guard(mutex, &data->irq_lock)
data->process_irqs = true;
if (regulator_is_enabled(data->regulator))
return 0;
}
/* clear any pending completion */
try_wait_for_completion(&data->complete);
ret = regulator_enable(data->regulator);
if (ret < 0)
return ret;
data->regulator_enabled = true;
usleep_range(CC2_STARTUP_TIME_US, CC2_STARTUP_TIME_US + 125);
scoped_guard(mutex, &data->irq_lock)
data->process_irqs = true;
data->process_irqs = true;
return 0;
}
@ -158,36 +140,15 @@ static void cc2_disable(struct cc2_data *data)
{
int err;
/* let the alarms already raised by the last measurement be processed */
if (data->irq_low > 0)
synchronize_irq(data->irq_low);
if (data->irq_high > 0)
synchronize_irq(data->irq_high);
/* ignore alarms triggered by voltage toggling when powering up */
scoped_guard(mutex, &data->irq_lock)
data->process_irqs = false;
if (data->irq_ready > 0)
synchronize_irq(data->irq_ready);
data->process_irqs = false;
/* exclusive regulator, check in case an enable failed */
if (!data->regulator_enabled)
return;
err = regulator_disable(data->regulator);
if (err) {
dev_dbg(&data->client->dev, "Failed to disable device");
return;
if (regulator_is_enabled(data->regulator)) {
err = regulator_disable(data->regulator);
if (err)
dev_dbg(&data->client->dev, "Failed to disable device");
}
data->regulator_enabled = false;
}
static void cc2_disable_action(void *data)
{
cc2_disable(data);
}
static int cc2_cmd_response_diagnostic(struct device *dev, u8 status)
@ -206,13 +167,13 @@ static int cc2_cmd_response_diagnostic(struct device *dev, u8 status)
case CC2_RESPONSE_BUSY:
return -EBUSY;
case CC2_RESPONSE_NACK:
if (status & CC2_ERR_CORR_EEPROM)
if (resp & CC2_ERR_CORR_EEPROM)
dev_dbg(dev, "Command failed: corrected EEPROM\n");
if (status & CC2_ERR_UNCORR_EEPROM)
if (resp & CC2_ERR_UNCORR_EEPROM)
dev_dbg(dev, "Command failed: uncorrected EEPROM\n");
if (status & CC2_ERR_RAM_PARITY)
if (resp & CC2_ERR_RAM_PARITY)
dev_dbg(dev, "Command failed: RAM parity\n");
if (status & CC2_ERR_CONFIG_LOAD)
if (resp & CC2_ERR_RAM_PARITY)
dev_dbg(dev, "Command failed: configuration error\n");
return -ENODATA;
default:
@ -265,7 +226,7 @@ static int cc2_command_mode_start(struct cc2_data *data)
2 * CC2_RESP_START_CM_US);
}
ret = cc2_read_command_status(data->client);
if (ret != -ETIMEDOUT || i == CC2_CM_RETRIES - 1)
if (ret != -ETIMEDOUT || i == CC2_CM_RETRIES)
break;
/* command window missed, prepare for a retry */
@ -299,7 +260,8 @@ static int cc2_write_reg(struct cc2_data *data, u8 reg, u16 val)
if (ret < 0)
goto disable;
ret = i2c_smbus_write_word_swapped(data->client, reg, val);
cpu_to_be16s(&val);
ret = i2c_smbus_write_word_data(data->client, reg, val);
if (ret < 0)
goto disable;
@ -349,7 +311,7 @@ static int cc2_read_reg(struct cc2_data *data, u8 reg, u16 *val)
if (ret != CC2_EEPROM_DATA_LEN)
return ret < 0 ? ret : -EIO;
*val = get_unaligned_be16(&buf[1]);
*val = be16_to_cpup((__be16 *)&buf[1]);
return cc2_read_command_status(data->client);
}
@ -389,10 +351,10 @@ static int cc2_data_fetch(struct i2c_client *client,
switch (type) {
case hwmon_humidity:
*val = cc2_rh_convert(get_unaligned_be16(&data[0]));
*val = cc2_rh_convert(be16_to_cpup((__be16 *)&data[0]));
break;
case hwmon_temp:
*val = cc2_temp_convert(get_unaligned_be16(&data[2]));
*val = cc2_temp_convert(be16_to_cpup((__be16 *)&data[2]));
break;
default:
return -EINVAL;
@ -520,10 +482,8 @@ static irqreturn_t cc2_ready_interrupt(int irq, void *data)
{
struct cc2_data *cc2 = data;
scoped_guard(mutex, &cc2->irq_lock) {
if (cc2->process_irqs)
complete(&cc2->complete);
}
if (cc2->process_irqs)
complete(&cc2->complete);
return IRQ_HANDLED;
}
@ -532,12 +492,10 @@ static irqreturn_t cc2_low_interrupt(int irq, void *data)
{
struct cc2_data *cc2 = data;
scoped_guard(mutex, &cc2->irq_lock) {
if (cc2->process_irqs) {
hwmon_notify_event(cc2->hwmon, hwmon_humidity,
hwmon_humidity_min_alarm, 0);
cc2->rh_alarm.low_alarm = true;
}
if (cc2->process_irqs) {
hwmon_notify_event(cc2->hwmon, hwmon_humidity,
hwmon_humidity_min_alarm, 0);
cc2->rh_alarm.low_alarm = true;
}
return IRQ_HANDLED;
@ -547,12 +505,10 @@ static irqreturn_t cc2_high_interrupt(int irq, void *data)
{
struct cc2_data *cc2 = data;
scoped_guard(mutex, &cc2->irq_lock) {
if (cc2->process_irqs) {
hwmon_notify_event(cc2->hwmon, hwmon_humidity,
hwmon_humidity_max_alarm, 0);
cc2->rh_alarm.high_alarm = true;
}
if (cc2->process_irqs) {
hwmon_notify_event(cc2->hwmon, hwmon_humidity,
hwmon_humidity_max_alarm, 0);
cc2->rh_alarm.high_alarm = true;
}
return IRQ_HANDLED;
@ -568,13 +524,11 @@ static int cc2_humidity_min_alarm_status(struct cc2_data *data, long *val)
if (ret < 0)
return ret;
scoped_guard(mutex, &data->irq_lock) {
if (data->rh_alarm.low_alarm) {
*val = (measurement < min_hyst) ? 1 : 0;
data->rh_alarm.low_alarm = *val;
} else {
*val = 0;
}
if (data->rh_alarm.low_alarm) {
*val = (measurement < min_hyst) ? 1 : 0;
data->rh_alarm.low_alarm = *val;
} else {
*val = 0;
}
return 0;
@ -590,13 +544,11 @@ static int cc2_humidity_max_alarm_status(struct cc2_data *data, long *val)
if (ret < 0)
return ret;
scoped_guard(mutex, &data->irq_lock) {
if (data->rh_alarm.high_alarm) {
*val = (measurement > max_hyst) ? 1 : 0;
data->rh_alarm.high_alarm = *val;
} else {
*val = 0;
}
if (data->rh_alarm.high_alarm) {
*val = (measurement > max_hyst) ? 1 : 0;
data->rh_alarm.high_alarm = *val;
} else {
*val = 0;
}
return 0;
@ -679,47 +631,28 @@ static int cc2_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
}
}
static int cc2_get_irqs(struct cc2_data *data, struct device *dev)
{
data->irq_ready = fwnode_irq_get_byname(dev_fwnode(dev), "ready");
if (data->irq_ready == -EPROBE_DEFER)
return data->irq_ready;
if (data->irq_ready > 0)
init_completion(&data->complete);
data->irq_low = fwnode_irq_get_byname(dev_fwnode(dev), "low");
if (data->irq_low == -EPROBE_DEFER)
return data->irq_low;
if (data->irq_low > 0)
data->rh_alarm.low_alarm_visible = true;
data->irq_high = fwnode_irq_get_byname(dev_fwnode(dev), "high");
if (data->irq_high == -EPROBE_DEFER)
return data->irq_high;
if (data->irq_high > 0)
data->rh_alarm.high_alarm_visible = true;
return 0;
}
static int cc2_request_data_ready(struct cc2_data *data, struct device *dev)
static int cc2_request_ready_irq(struct cc2_data *data, struct device *dev)
{
int ret = 0;
if (data->irq_ready > 0)
data->irq_ready = fwnode_irq_get_byname(dev_fwnode(dev), "ready");
if (data->irq_ready > 0) {
init_completion(&data->complete);
ret = devm_request_threaded_irq(dev, data->irq_ready, NULL,
cc2_ready_interrupt,
IRQF_ONESHOT |
IRQF_TRIGGER_RISING,
dev_name(dev), data);
}
return ret;
}
static int cc2_request_alarms(struct cc2_data *data, struct device *dev)
static int cc2_request_alarm_irqs(struct cc2_data *data, struct device *dev)
{
int ret = 0;
data->irq_low = fwnode_irq_get_byname(dev_fwnode(dev), "low");
if (data->irq_low > 0) {
ret = devm_request_threaded_irq(dev, data->irq_low, NULL,
cc2_low_interrupt,
@ -728,8 +661,11 @@ static int cc2_request_alarms(struct cc2_data *data, struct device *dev)
dev_name(dev), data);
if (ret)
return ret;
data->rh_alarm.low_alarm_visible = true;
}
data->irq_high = fwnode_irq_get_byname(dev_fwnode(dev), "high");
if (data->irq_high > 0) {
ret = devm_request_threaded_irq(dev, data->irq_high, NULL,
cc2_high_interrupt,
@ -738,6 +674,8 @@ static int cc2_request_alarms(struct cc2_data *data, struct device *dev)
dev_name(dev), data);
if (ret)
return ret;
data->rh_alarm.high_alarm_visible = true;
}
return ret;
@ -779,8 +717,6 @@ static int cc2_probe(struct i2c_client *client)
i2c_set_clientdata(client, data);
mutex_init(&data->irq_lock);
data->client = client;
data->regulator = devm_regulator_get_exclusive(dev, "vdd");
@ -790,18 +726,14 @@ static int cc2_probe(struct i2c_client *client)
device_property_read_string(dev, "label", &data->label);
ret = cc2_get_irqs(data, dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to get IRQs\n");
ret = devm_add_action_or_reset(dev, cc2_disable_action, data);
if (ret)
return ret;
ret = cc2_request_data_ready(data, dev);
ret = cc2_request_ready_irq(data, dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to request ready irq\n");
ret = cc2_request_alarm_irqs(data, dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to request alarm irqs\n");
data->hwmon = devm_hwmon_device_register_with_info(dev, client->name,
data, &cc2_chip_info,
NULL);
@ -809,13 +741,16 @@ static int cc2_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(data->hwmon),
"Failed to register hwmon device\n");
ret = cc2_request_alarms(data, dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to request alarm irqs\n");
return 0;
}
static void cc2_remove(struct i2c_client *client)
{
struct cc2_data *data = i2c_get_clientdata(client);
cc2_disable(data);
}
static const struct i2c_device_id cc2_id[] = {
{ .name = "cc2d23" },
{ .name = "cc2d23s" },
@ -848,6 +783,7 @@ static struct i2c_driver cc2_driver = {
.of_match_table = cc2_of_match,
},
.probe = cc2_probe,
.remove = cc2_remove,
.id_table = cc2_id,
};
module_i2c_driver(cc2_driver);

View File

@ -76,7 +76,7 @@ struct temp_data {
int temp;
bool temp_valid;
int tjmax;
u64 last_updated;
unsigned long last_updated;
unsigned int cpu;
int index;
u32 cpu_core_id;
@ -407,7 +407,7 @@ static ssize_t show_temp(struct device *dev,
mutex_lock(&tdata->update_lock);
/* Check whether the time interval has elapsed */
if (time_after64(get_jiffies_64(), tdata->last_updated + HZ)) {
if (time_after(jiffies, tdata->last_updated + HZ)) {
tjmax = get_tjmax(tdata, dev);
rdmsrq_on_cpu(tdata->cpu, tdata->status_reg, &val.q);
/*
@ -417,7 +417,7 @@ static ssize_t show_temp(struct device *dev,
*/
tdata->temp_valid = (val.l >> 31) & 1;
tdata->temp = tjmax - ((val.l >> 16) & 0xff) * 1000;
tdata->last_updated = get_jiffies_64();
tdata->last_updated = jiffies;
}
valid = tdata->temp_valid;
@ -491,12 +491,11 @@ init_temp_data(struct platform_data *pdata, unsigned int cpu, int pkg_flag)
struct temp_data *tdata;
if (!pdata->core_data) {
int nr_cores = topology_num_cores_per_package();
pdata->core_data = kzalloc_objs(struct temp_data *, nr_cores);
pdata->nr_cores = topology_num_cores_per_package();
pdata->core_data = kzalloc_objs(struct temp_data *,
pdata->nr_cores);
if (!pdata->core_data)
return NULL;
pdata->nr_cores = nr_cores;
}
tdata = kzalloc_obj(struct temp_data);
@ -521,8 +520,11 @@ init_temp_data(struct platform_data *pdata, unsigned int cpu, int pkg_flag)
tdata->cpu = cpu;
tdata->cpu_core_id = topology_core_id(cpu);
tdata->attr_size = MAX_CORE_ATTRS;
/* Backdate to force a refresh on the first read */
tdata->last_updated = get_jiffies_64() - HZ - 1;
/*
* A zero timestamp does not look stale on 32-bit, where jiffies
* starts just short of wrapping. Backdate it instead.
*/
tdata->last_updated = jiffies - HZ - 1;
mutex_init(&tdata->update_lock);
return tdata;
}
@ -693,9 +695,6 @@ static int coretemp_cpu_online(unsigned int cpu)
if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
return 0;
if (!pdev)
return 0;
pdata = platform_get_drvdata(pdev);
if (!pdata->hwmon_dev) {
struct device *hwmon;
@ -747,9 +746,6 @@ static int coretemp_cpu_offline(unsigned int cpu)
return 0;
/* If the physical CPU device does not exist, just return */
if (!pdev)
return 0;
pd = platform_get_drvdata(pdev);
if (!pd->hwmon_dev)
return 0;

View File

@ -215,11 +215,10 @@ static int set_target(struct ccp_device *ccp, int channel, long val)
int ret;
val = clamp_val(val, 0, 0xFFFF);
ccp->target[channel] = val;
mutex_lock(&ccp->mutex);
ret = send_usb_cmd(ccp, CTL_SET_FAN_TARGET, channel, val >> 8, val);
if (!ret)
ccp->target[channel] = val;
mutex_unlock(&ccp->mutex);
return ret;

View File

@ -444,7 +444,6 @@ static void gpd_duo_set_pwm_enable(struct gpd_fan_data *data, enum FAN_PWM_ENABL
break;
case AUTOMATIC:
gpd_ecram_write(data->drvdata, data->drvdata->pwm_write, 0);
gpd_ecram_write(data->drvdata, data->drvdata->pwm_write + 1, 0);
break;
}
}

View File

@ -150,10 +150,7 @@ static int set_fan_speed(struct gpio_fan_data *fan_data, int speed_index)
__set_fan_ctrl(fan_data, fan_data->speed[speed_index].ctrl_val);
/* The GPIOs have changed, and a PM put drops the reference on error. */
fan_data->speed_index = speed_index;
if (speed_index == 0) {
if (fan_data->speed_index > 0 && speed_index == 0) {
int ret;
ret = pm_runtime_put_sync(fan_data->dev);
@ -161,6 +158,8 @@ static int set_fan_speed(struct gpio_fan_data *fan_data, int speed_index)
return ret;
}
fan_data->speed_index = speed_index;
return 0;
}

View File

@ -390,7 +390,6 @@ struct hp_wmi_info {
*/
struct hp_wmi_sensors {
struct wmi_device *wdev;
struct hwmon_chip_info chip_info;
struct hp_wmi_info **info_map[hwmon_max];
u8 channel_count[hwmon_max];
bool has_intrusion;
@ -739,21 +738,15 @@ static long scale_numeric_sensor(const struct hp_wmi_numeric_sensor *nsensor)
val = current_reading;
for (; val && unit_modifier < target_modifier; unit_modifier++)
for (; unit_modifier < target_modifier; unit_modifier++)
val = DIV_ROUND_CLOSEST(val, 10);
if (val) {
for (; unit_modifier > target_modifier; unit_modifier--) {
if (val > LONG_MAX / 10) {
val = LONG_MAX;
break;
}
if (val < LONG_MIN / 10) {
val = LONG_MIN;
break;
}
val *= 10;
for (; unit_modifier > target_modifier; unit_modifier--) {
if (val > LONG_MAX / 10) {
val = LONG_MAX;
break;
}
val *= 10;
}
if (sensor_type == HP_WMI_TYPE_TEMPERATURE) {
@ -1480,10 +1473,8 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
if ((type == hwmon_temp && attr == hwmon_temp_alarm) ||
(type == hwmon_fan && attr == hwmon_fan_alarm)) {
mutex_lock(&state->lock);
*out_val = info->alarm ? 1 : 0;
info->alarm = false;
mutex_unlock(&state->lock);
return 0;
}
@ -1540,6 +1531,11 @@ static const struct hwmon_ops hp_wmi_hwmon_ops = {
.write = hp_wmi_hwmon_write,
};
static struct hwmon_chip_info hp_wmi_chip_info = {
.ops = &hp_wmi_hwmon_ops,
.info = NULL,
};
static struct hp_wmi_info *match_fan_event(struct hp_wmi_sensors *state,
const char *event_description)
{
@ -1966,8 +1962,7 @@ static int make_chip_info(struct hp_wmi_sensors *state, bool has_events)
if (!ptr_channel_info)
return -ENOMEM;
state->chip_info.ops = &hp_wmi_hwmon_ops;
state->chip_info.info = ptr_channel_info;
hp_wmi_chip_info.info = ptr_channel_info;
for (type = hwmon_chip; type < hwmon_max; type++) {
count = channel_count[type];
@ -2058,7 +2053,7 @@ static int hp_wmi_sensors_init(struct hp_wmi_sensors *state)
return err;
hwdev = devm_hwmon_device_register_with_info(dev, "hp_wmi_sensors",
state, &state->chip_info,
state, &hp_wmi_chip_info,
NULL);
return PTR_ERR_OR_ZERO(hwdev);
}

View File

@ -123,7 +123,8 @@ struct lm75_data {
static const u8 lm75_sample_set_masks[] = { 0 << 5, 1 << 5, 2 << 5, 3 << 5 };
#define LM75_ALERT_POLARITY_HIGH_BIT BIT(2)
#define LM75_ALERT_POLARITY_HIGH_8_BIT (BIT(2))
#define LM75_ALERT_POLARITY_HIGH_16_BIT (BIT(2) << 8)
#define LM75_SAMPLE_CLEAR_MASK (3 << 5)
/* The structure below stores the configuration values of the supported devices.
@ -769,7 +770,11 @@ static int lm75_generic_probe(struct device *dev, const char *name,
data->orig_conf = status;
/* Enforce polarity active-low (default) or active-high (devicetree) */
pol_mask = LM75_ALERT_POLARITY_HIGH_BIT;
if (!data->params->config_reg_16bits)
pol_mask = LM75_ALERT_POLARITY_HIGH_8_BIT;
else
pol_mask = LM75_ALERT_POLARITY_HIGH_16_BIT;
clr_mask = data->params->clr_mask | pol_mask;
set_mask = data->params->set_mask & ~pol_mask;
if (device_property_read_bool(dev, "ti,alert-polarity-active-high"))

View File

@ -606,16 +606,13 @@ static DEVICE_ATTR_RO(cpu0_vid);
static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct i2c_client *client = dev_get_drvdata(dev);
struct lm87_data *data = i2c_get_clientdata(client);
struct lm87_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", data->vrm);
}
static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = dev_get_drvdata(dev);
struct lm87_data *data = i2c_get_clientdata(client);
struct lm87_data *data = dev_get_drvdata(dev);
unsigned long val;
int err;

View File

@ -920,7 +920,7 @@ static ssize_t
show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
{
struct nct6683_data *data = nct6683_update_device(dev);
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
int index = sattr->index;
return sprintf(buf, "%d\n", data->pwm[index]);
@ -930,7 +930,7 @@ static ssize_t
store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
struct nct6683_data *data = dev_get_drvdata(dev);
int index = sattr->index;
unsigned long val;

View File

@ -4,6 +4,7 @@
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/devm-helpers.h>
#include <linux/hwmon.h>
#include <linux/jiffies.h>
#include <linux/module.h>
@ -325,13 +326,11 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv)
if (ret == -ENODEV) {
dev_dbg(priv->dev, "No DIMMs found\n");
return 0;
}
if (ret == -EAGAIN) {
} else if (ret) {
schedule_delayed_work(&priv->detect_work, DIMM_MASK_CHECK_DELAY_JIFFIES);
dev_dbg(priv->dev, "Deferred populating DIMM temp info\n");
}
if (ret)
return ret;
}
channels = priv->gen_info->chan_rank_max * priv->gen_info->dimm_idx_max;
@ -399,8 +398,10 @@ static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxil
"Unexpected PECI revision %#x, some features may be unavailable\n",
peci_dev->info.peci_revision);
auxiliary_set_drvdata(adev, priv);
INIT_DELAYED_WORK(&priv->detect_work, create_dimm_temp_info_delayed);
ret = devm_delayed_work_autocancel(priv->dev, &priv->detect_work,
create_dimm_temp_info_delayed);
if (ret)
return ret;
ret = create_dimm_temp_info(priv);
if (ret && ret != -EAGAIN) {
@ -411,13 +412,6 @@ static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxil
return 0;
}
static void peci_dimmtemp_remove(struct auxiliary_device *adev)
{
struct peci_dimmtemp *priv = auxiliary_get_drvdata(adev);
cancel_delayed_work_sync(&priv->detect_work);
}
static int
read_thresholds_hsx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
{
@ -671,7 +665,6 @@ MODULE_DEVICE_TABLE(auxiliary, peci_dimmtemp_ids);
static struct auxiliary_driver peci_dimmtemp_driver = {
.probe = peci_dimmtemp_probe,
.remove = peci_dimmtemp_remove,
.id_table = peci_dimmtemp_ids,
};

View File

@ -1524,22 +1524,14 @@ static int pmbus_thermal_add_sensor(struct pmbus_data *pmbus_data,
tdata->sensor = sensor;
tdata->pmbus_data = pmbus_data;
/*
* The PMBus core numbers its temperature sensors from 1, as the
* hwmon tempN attributes, while the thermal core expects a 0-based
* sensor index.
*/
tzd = devm_thermal_of_zone_register(dev, index - 1, tdata,
tzd = devm_thermal_of_zone_register(dev, index, tdata,
&pmbus_thermal_ops);
/*
* If CONFIG_THERMAL_OF is disabled, devm_thermal_of_zone_register()
* returns -ENOTSUPP. If no thermal zone is configured for the sensor,
* it returns -ENODEV. Ignore those errors but forward any other error.
* If CONFIG_THERMAL_OF is disabled, this returns -ENODEV,
* so ignore that error but forward any other error.
*/
if (IS_ERR(tzd) && PTR_ERR(tzd) != -ENODEV && PTR_ERR(tzd) != -ENOTSUPP) {
devm_kfree(dev, tdata);
if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV))
return PTR_ERR(tzd);
}
return 0;
}
@ -1554,11 +1546,10 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
{
struct sensor_device_attribute *a;
struct pmbus_sensor *sensor;
int err;
sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL);
if (!sensor)
return ERR_PTR(-ENOMEM);
return NULL;
a = &sensor->attribute;
if (type)
@ -1583,17 +1574,14 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
pmbus_set_sensor, -1);
if (pmbus_add_attribute(data, &a->dev_attr.attr))
return ERR_PTR(-ENOMEM);
return NULL;
sensor->next = data->sensors;
data->sensors = sensor;
/* temperature sensors with _input values are registered with thermal */
if (class == PSC_TEMPERATURE && strcmp(type, "input") == 0) {
err = pmbus_thermal_add_sensor(data, sensor, seq);
if (err)
return ERR_PTR(err);
}
if (class == PSC_TEMPERATURE && strcmp(type, "input") == 0)
pmbus_thermal_add_sensor(data, sensor, seq);
return sensor;
}
@ -1694,8 +1682,8 @@ static int pmbus_add_limit_attrs(struct i2c_client *client,
page, 0xff, l->reg, attr->class,
attr->update || l->update,
l->readonly, l->writeonly, true);
if (IS_ERR(curr))
return PTR_ERR(curr);
if (!curr)
return -ENOMEM;
if (l->sbit && (info->func[page] & attr->sfunc)) {
ret = pmbus_add_boolean(data, name,
l->alarm, index,
@ -1734,8 +1722,8 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
}
base = pmbus_add_sensor(data, name, "input", index, page, phase,
attr->reg, attr->class, true, true, false, true);
if (IS_ERR(base))
return PTR_ERR(base);
if (!base)
return -ENOMEM;
/* No limit and alarm attributes for phase specific sensors */
if (attr->sfunc && phase == 0xff) {
ret = pmbus_add_limit_attrs(client, data, info, name,
@ -2408,8 +2396,8 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN,
false, false, false, true);
if (IS_ERR(sensor))
return PTR_ERR(sensor);
if (!sensor)
return -ENOMEM;
if (!((data->info->func[page] & PMBUS_HAVE_PWM12) ||
(data->info->func[page] & PMBUS_HAVE_PWM34)))
@ -2419,15 +2407,15 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
0xff, PMBUS_VIRT_PWM_1 + id, PSC_PWM,
false, false, false, true);
if (IS_ERR(sensor))
return PTR_ERR(sensor);
if (!sensor)
return -ENOMEM;
sensor = pmbus_add_sensor(data, "pwm", "enable", index, page,
0xff, PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM,
true, false, false, false);
if (IS_ERR(sensor))
return PTR_ERR(sensor);
if (!sensor)
return -ENOMEM;
return 0;
}
@ -2444,7 +2432,6 @@ static int pmbus_add_fan_attributes(struct i2c_client *client,
int f;
for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) {
struct pmbus_sensor *sensor;
int regval;
if (!(info->func[page] & pmbus_fan_flags[f]))
@ -2465,11 +2452,10 @@ static int pmbus_add_fan_attributes(struct i2c_client *client,
(!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4)))))
continue;
sensor = pmbus_add_sensor(data, "fan", "input", index,
page, 0xff, pmbus_fan_registers[f],
PSC_FAN, true, true, false, true);
if (IS_ERR(sensor))
return PTR_ERR(sensor);
if (pmbus_add_sensor(data, "fan", "input", index,
page, 0xff, pmbus_fan_registers[f],
PSC_FAN, true, true, false, true) == NULL)
return -ENOMEM;
/* Fan control */
if (pmbus_check_word_register(client, page,

View File

@ -351,8 +351,6 @@ static int q54sj108a2_probe(struct i2c_client *client)
psu->client = client;
debugfs = pmbus_get_debugfs_dir(client);
if (!debugfs)
return 0;
q54sj108a2_dir = debugfs_create_dir(client->name, debugfs);

View File

@ -31,7 +31,6 @@
#include <linux/bitrev.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/workqueue.h>
/* Commands */
#define SHT15_MEASURE_TEMP 0x03
@ -977,22 +976,25 @@ static int sht15_probe(struct platform_device *pdev)
goto err_release_reg;
}
ret = request_irq(gpiod_to_irq(data->data), sht15_interrupt_fired,
IRQF_TRIGGER_FALLING, "sht15 data", data);
ret = devm_request_irq(&pdev->dev, gpiod_to_irq(data->data),
sht15_interrupt_fired,
IRQF_TRIGGER_FALLING,
"sht15 data",
data);
if (ret)
goto err_release_reg;
disable_irq_nosync(gpiod_to_irq(data->data));
ret = sht15_connection_reset(data);
if (ret)
goto err_free_irq;
goto err_release_reg;
ret = sht15_soft_reset(data);
if (ret)
goto err_free_irq;
goto err_release_reg;
ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
if (ret) {
dev_err(&pdev->dev, "sysfs create failed\n");
goto err_free_irq;
goto err_release_reg;
}
data->hwmon_dev = hwmon_device_register(data->dev);
@ -1005,13 +1007,9 @@ static int sht15_probe(struct platform_device *pdev)
err_release_sysfs_group:
sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
err_free_irq:
disable_work_sync(&data->read_work);
free_irq(gpiod_to_irq(data->data), data);
err_release_reg:
if (!IS_ERR(data->reg)) {
regulator_unregister_notifier(data->reg, &data->nb);
cancel_work_sync(&data->update_supply_work);
regulator_disable(data->reg);
}
return ret;
@ -1025,16 +1023,12 @@ static void sht15_remove(struct platform_device *pdev)
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
disable_work_sync(&data->read_work);
free_irq(gpiod_to_irq(data->data), data);
ret = sht15_soft_reset(data);
if (ret)
dev_err(&pdev->dev, "Failed to reset device (%pe)\n", ERR_PTR(ret));
if (!IS_ERR(data->reg)) {
regulator_unregister_notifier(data->reg, &data->nb);
cancel_work_sync(&data->update_supply_work);
regulator_disable(data->reg);
}
}

View File

@ -111,9 +111,7 @@ static int sht4x_read_values(struct sht4x_data *data)
}
if (data->data_pending &&
time_before64(get_jiffies_64(),
data->heating_complete +
msecs_to_jiffies(data->update_interval))) {
time_before64(get_jiffies_64(), data->heating_complete + data->update_interval)) {
data->data_pending = false;
} else {
next_update = data->last_updated +

View File

@ -13,7 +13,7 @@
#include <linux/i2c.h>
#include <linux/i3c/device.h>
#include <linux/init.h>
#include <linux/ktime.h>
#include <linux/jiffies.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
@ -78,7 +78,7 @@
struct tmp108 {
struct regmap *regmap;
u16 orig_config;
ktime_t ready_time;
u64 ready_time;
const struct tmp108_params *params;
};
@ -121,7 +121,6 @@ static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,
struct tmp108 *tmp108 = dev_get_drvdata(dev);
unsigned int regval;
int err, hyst;
s64 delay;
if (type == hwmon_chip) {
if (attr == hwmon_chip_update_interval) {
@ -138,10 +137,12 @@ static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,
switch (attr) {
case hwmon_temp_input:
/* Wait if it is too early to return a conversion */
delay = ktime_us_delta(tmp108->ready_time, ktime_get());
if (delay > 0)
usleep_range(delay, delay + 1000);
/* Is it too early to return a conversion ? */
if (time_before64(get_jiffies_64(), tmp108->ready_time)) {
dev_dbg(dev, "%s: Conversion not ready yet..\n",
__func__);
return -EAGAIN;
}
err = regmap_read(tmp108->regmap, TMP108_REG_TEMP, &regval);
if (err < 0)
return err;
@ -476,8 +477,11 @@ static int tmp108_common_probe(struct device *dev, struct regmap *regmap, char *
return err;
}
tmp108->ready_time = ktime_add_ms(ktime_get(),
TMP108_CONVERSION_TIME_MS);
tmp108->ready_time = get_jiffies_64();
if ((tmp108->orig_config & TMP108_CONF_MODE_MASK) ==
TMP108_MODE_SHUTDOWN)
tmp108->ready_time +=
msecs_to_jiffies(TMP108_CONVERSION_TIME_MS);
err = devm_add_action_or_reset(dev, tmp108_restore_config, tmp108);
if (err) {
@ -524,8 +528,8 @@ static int tmp108_resume(struct device *dev)
err = regmap_update_bits(tmp108->regmap, TMP108_REG_CONF,
TMP108_CONF_MODE_MASK, TMP108_MODE_CONTINUOUS);
tmp108->ready_time = ktime_add_ms(ktime_get(),
TMP108_CONVERSION_TIME_MS);
tmp108->ready_time = get_jiffies_64() +
msecs_to_jiffies(TMP108_CONVERSION_TIME_MS);
return err;
}

View File

@ -1227,12 +1227,12 @@ static int viommu_probe(struct virtio_device *vdev)
/* Populate the event queue with buffers */
ret = viommu_fill_evtq(viommu);
if (ret)
goto err_reset_vdev;
goto err_free_vqs;
ret = iommu_device_sysfs_add(&viommu->iommu, dev, NULL, "%s",
virtio_bus_name(vdev));
if (ret)
goto err_reset_vdev;
goto err_free_vqs;
vdev->priv = viommu;
@ -1244,8 +1244,6 @@ static int viommu_probe(struct virtio_device *vdev)
return 0;
err_reset_vdev:
virtio_reset_device(vdev);
err_free_vqs:
vdev->config->del_vqs(vdev);

View File

@ -2779,27 +2779,6 @@ static void bond_miimon_link_change(struct bonding *bond,
}
}
static bool bond_miimon_slave_down(struct bonding *bond,
struct slave *slave)
{
if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
bond_set_slave_link_state(slave, BOND_LINK_DOWN,
BOND_SLAVE_NOTIFY_NOW);
if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP ||
BOND_MODE(bond) == BOND_MODE_8023AD)
bond_set_slave_inactive_flags(slave,
BOND_SLAVE_NOTIFY_NOW);
slave_info(bond->dev, slave->dev, "link status definitely down, disabling slave\n");
bond_miimon_link_change(bond, slave, BOND_LINK_DOWN);
return slave == rcu_access_pointer(bond->curr_active_slave);
}
static void bond_miimon_commit(struct bonding *bond)
{
struct slave *slave, *primary, *active;
@ -2828,22 +2807,10 @@ static void bond_miimon_commit(struct bonding *bond)
err = bond_update_speed_duplex(slave);
netdev_unlock_ops(slave->dev);
if (err && bond_needs_speed_duplex(bond)) {
slave->link = BOND_LINK_DOWN;
if (net_ratelimit())
slave_warn(bond->dev, slave->dev,
"failed to get link speed/duplex\n");
/* Coming from FAIL/UP, the slave may still be
* in use and may be curr_active_slave, so take
* it through the full down path. Coming from
* DOWN/BACK, it was never brought up, so just
* revert it to DOWN.
*/
if (slave->link == BOND_LINK_FAIL ||
slave->link == BOND_LINK_UP) {
if (bond_miimon_slave_down(bond, slave))
do_failover = true;
continue;
}
slave->link = BOND_LINK_DOWN;
continue;
}
bond_set_slave_link_state(slave, BOND_LINK_UP,
@ -2872,13 +2839,28 @@ static void bond_miimon_commit(struct bonding *bond)
continue;
case BOND_LINK_DOWN:
if (bond_miimon_slave_down(bond, slave))
if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
bond_set_slave_link_state(slave, BOND_LINK_DOWN,
BOND_SLAVE_NOTIFY_NOW);
if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP ||
BOND_MODE(bond) == BOND_MODE_8023AD)
bond_set_slave_inactive_flags(slave,
BOND_SLAVE_NOTIFY_NOW);
slave_info(bond->dev, slave->dev, "link status definitely down, disabling slave\n");
bond_miimon_link_change(bond, slave, BOND_LINK_DOWN);
if (slave == rcu_access_pointer(bond->curr_active_slave))
do_failover = true;
continue;
case BOND_LINK_FAIL:
case BOND_LINK_BACK:
bond_commit_link_state(slave, BOND_SLAVE_NOTIFY_LATER);
slave_dbg(bond->dev, slave->dev, "link_new_state %d on slave\n",
slave->link_new_state);
continue;
@ -2912,6 +2894,8 @@ static void bond_mii_monitor(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
mii_work.work);
struct list_head *iter;
struct slave *slave;
unsigned long delay;
bool commit;
@ -2933,8 +2917,13 @@ static void bond_mii_monitor(struct work_struct *work)
goto re_arm;
}
if (commit)
if (commit) {
bond_for_each_slave(bond, slave, iter) {
bond_commit_link_state(slave,
BOND_SLAVE_NOTIFY_LATER);
}
bond_miimon_commit(bond);
}
if (bond->send_peer_notif)
bond_peer_notify_may_events(bond, true);
@ -3984,13 +3973,18 @@ static int bond_slave_netdev_event(unsigned long event,
case NETDEV_CHANGE:
/* For 802.3ad mode only:
* Getting invalid Speed/Duplex values here will put slave
* in weird state. Mark an up slave as link-fail and let
* miimon set it right when correct speed/duplex are available.
* in weird state. Mark it as link-fail if the link was
* previously up or link-down if it hasn't yet come up, and
* let link-monitoring (miimon) set it right when correct
* speeds/duplex are available.
*/
if (bond_update_speed_duplex(slave) &&
BOND_MODE(bond) == BOND_MODE_8023AD &&
slave->link == BOND_LINK_UP)
slave->link = BOND_LINK_FAIL;
BOND_MODE(bond) == BOND_MODE_8023AD) {
if (slave->last_link_up)
slave->link = BOND_LINK_FAIL;
else
slave->link = BOND_LINK_DOWN;
}
if (BOND_MODE(bond) == BOND_MODE_8023AD)
bond_3ad_adapter_speed_duplex_changed(slave);

View File

@ -720,8 +720,7 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
return 0;
}
static size_t can_tdc_get_size(const struct net_device *dev,
struct data_bittiming_params *dbt_params,
static size_t can_tdc_get_size(struct data_bittiming_params *dbt_params,
u32 tdc_flags)
{
bool tdc_manual = tdc_flags & CAN_CTRLMODE_TDC_MANUAL_MASK;
@ -743,8 +742,7 @@ static size_t can_tdc_get_size(const struct net_device *dev,
}
if (tdc_flags) {
if (tdc_manual ||
(dbt_params->do_get_auto_tdcv && netif_running(dev)))
if (tdc_manual || dbt_params->do_get_auto_tdcv)
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCV */
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_TDCO */
if (dbt_params->tdc_const->tdcf_max)
@ -754,8 +752,7 @@ static size_t can_tdc_get_size(const struct net_device *dev,
return size;
}
static size_t can_data_bittiming_get_size(const struct net_device *dev,
struct data_bittiming_params *dbt_params,
static size_t can_data_bittiming_get_size(struct data_bittiming_params *dbt_params,
u32 tdc_flags)
{
size_t size = 0;
@ -767,7 +764,7 @@ static size_t can_data_bittiming_get_size(const struct net_device *dev,
if (dbt_params->data_bitrate_const) /* IFLA_CAN_{,XL}_DATA_BITRATE_CONST */
size += nla_total_size(sizeof(*dbt_params->data_bitrate_const) *
dbt_params->data_bitrate_const_cnt);
size += can_tdc_get_size(dev, dbt_params, tdc_flags);/* IFLA_CAN_{,XL}_TDC */
size += can_tdc_get_size(dbt_params, tdc_flags);/* IFLA_CAN_{,XL}_TDC */
return size;
}
@ -815,7 +812,7 @@ static size_t can_get_size(const struct net_device *dev)
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */
size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
if (priv->do_get_berr_counter && netif_running(dev)) /* IFLA_CAN_BERR_COUNTER */
if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */
size += nla_total_size(sizeof(struct can_berr_counter));
if (priv->termination_const) {
size += nla_total_size(sizeof(priv->termination)); /* IFLA_CAN_TERMINATION */
@ -828,10 +825,10 @@ static size_t can_get_size(const struct net_device *dev)
size += sizeof(priv->bitrate_max); /* IFLA_CAN_BITRATE_MAX */
size += can_ctrlmode_ext_get_size(); /* IFLA_CAN_CTRLMODE_EXT */
size += can_data_bittiming_get_size(dev, &priv->fd,
size += can_data_bittiming_get_size(&priv->fd,
priv->ctrlmode & CAN_CTRLMODE_FD_TDC_MASK);
size += can_data_bittiming_get_size(dev, &priv->xl,
size += can_data_bittiming_get_size(&priv->xl,
priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MASK);
size += can_pwm_get_size(priv->xl.pwm_const, /* IFLA_CAN_XL_PWM */
priv->ctrlmode & CAN_CTRLMODE_XL_TMS);
@ -913,7 +910,7 @@ static int can_tdc_fill_info(struct sk_buff *skb, const struct net_device *dev,
if (tdc_manual) {
tdcv = tdc->tdcv;
err = 0;
} else if (dbt_params->do_get_auto_tdcv && netif_running(dev)) {
} else if (dbt_params->do_get_auto_tdcv) {
err = dbt_params->do_get_auto_tdcv(dev, &tdcv);
}
if (!err && nla_put_u32(skb, IFLA_CAN_TDC_TDCV, tdcv))
@ -1009,7 +1006,7 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) ||
nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) ||
(priv->do_get_berr_counter && netif_running(dev) &&
(priv->do_get_berr_counter &&
!priv->do_get_berr_counter(dev, &bec) &&
nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) ||

View File

@ -4,7 +4,6 @@
* Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
*/
#include <linux/can/can-ml.h>
#include <linux/can/dev.h>
#include <linux/module.h>
#include <net/can.h>
@ -55,7 +54,6 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
if (idx >= priv->echo_skb_max) {
netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
__func__, idx, priv->echo_skb_max);
dev_kfree_skb_any(skb);
return -EINVAL;
}
@ -64,7 +62,7 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
(skb->protocol != htons(ETH_P_CAN) &&
skb->protocol != htons(ETH_P_CANFD) &&
skb->protocol != htons(ETH_P_CANXL))) {
dev_kfree_skb_any(skb);
kfree_skb(skb);
return 0;
}
@ -92,7 +90,7 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
} else {
/* locking problem with netif_stop_queue() ?? */
netdev_err(dev, "%s: BUG! echo_skb %d is occupied!\n", __func__, idx);
dev_kfree_skb_any(skb);
kfree_skb(skb);
return -EBUSY;
}
@ -229,7 +227,7 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
csx = can_skb_ext_add(skb);
if (!csx) {
dev_kfree_skb_any(skb);
kfree_skb(skb);
goto out_error_cc;
}
@ -260,7 +258,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,
csx = can_skb_ext_add(skb);
if (!csx) {
dev_kfree_skb_any(skb);
kfree_skb(skb);
goto out_error_fd;
}
@ -298,7 +296,7 @@ struct sk_buff *alloc_canxl_skb(struct net_device *dev,
csx = can_skb_ext_add(skb);
if (!csx) {
dev_kfree_skb_any(skb);
kfree_skb(skb);
goto out_error_xl;
}
@ -390,7 +388,7 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
break;
case ETH_P_CANXL:
if (!can_cap_enabled(dev, CAN_CAP_XL) || !can_is_canxl_skb(skb))
if (!can_is_canxl_skb(skb))
goto inval_skb;
break;
@ -404,7 +402,7 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
return false;
inval_skb:
dev_kfree_skb_any(skb);
kfree_skb(skb);
dev->stats.tx_dropped++;
return true;
}

View File

@ -755,7 +755,7 @@ static int pcan_usb_fd_decode_buf(struct peak_usb_device *dev, struct urb *urb)
u16 rx_msg_type, rx_msg_size;
size_t rx_msg_min_size;
if (msg_end - msg_ptr < sizeof(rx_msg->size)) {
if (msg_end - msg_ptr < sizeof(*rx_msg)) {
err = -EBADMSG;
break;
}
@ -766,11 +766,6 @@ static int pcan_usb_fd_decode_buf(struct peak_usb_device *dev, struct urb *urb)
break;
}
if (msg_end - msg_ptr < sizeof(*rx_msg)) {
err = -EBADMSG;
break;
}
rx_msg_size = le16_to_cpu(rx_msg->size);
rx_msg_type = le16_to_cpu(rx_msg->type);

View File

@ -836,59 +836,6 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port)
}
EXPORT_SYMBOL(b53_brcm_hdr_setup);
int b53_enable_mcast_snooping(struct b53_device *dev)
{
u16 val16;
u32 val;
int ret;
/* Older switches use different IGMP controls, not HL_PRTC_CTRL. */
if (is5325(dev) || is5365(dev) || dev->chip_id == BCM5389_DEVICE_ID ||
is5397_98(dev) || is63xx(dev))
return 0;
/* IGMPv2 and MLDv1 reports use the group's destination MAC. Once
* the first listener is offloaded, ordinary multicast forwarding
* can keep subsequent reports from reaching the bridge CPU.
*/
/* BCM5395 has a narrower register and a single IGMP classifier.
* Its ICMPv6 classifier also covers MLD.
*/
if (dev->chip_id == BCM5395_DEVICE_ID) {
ret = b53_read16(dev, B53_MGMT_PAGE, B53_HL_PRTC_CTRL, &val16);
if (ret)
return ret;
val16 |= HL_PRTC_IGMP_IP_EN_5395 | HL_PRTC_ICMPV6_EN;
/* Zero forwarding modes copy control traffic to the CPU
* independently of the ARL lookup, retaining L2 forwarding.
*/
val16 &= ~(HL_PRTC_IGMP_FWD_MODE_5395 |
HL_PRTC_ICMPV6_FWD_MODE);
return b53_write16(dev, B53_MGMT_PAGE, B53_HL_PRTC_CTRL,
val16);
}
ret = b53_read32(dev, B53_MGMT_PAGE, B53_HL_PRTC_CTRL, &val);
if (ret)
return ret;
val |= HL_PRTC_IGMP_RPTLVE_EN | HL_PRTC_IGMP_QRY_EN |
HL_PRTC_IGMP_UKN_EN | HL_PRTC_MLD_RPTDONE_EN |
HL_PRTC_MLD_QRY_EN;
/* Zero forwarding modes copy control traffic to the CPU
* independently of the ARL lookup, retaining L2 forwarding.
*/
val &= ~(HL_PRTC_IGMP_RPTLVE_FWD_MODE | HL_PRTC_IGMP_QRY_FWD_MODE |
HL_PRTC_IGMP_UKN_FWD_MODE | HL_PRTC_MLD_RPTDONE_FWD_MODE |
HL_PRTC_MLD_QRY_FWD_MODE);
return b53_write32(dev, B53_MGMT_PAGE, B53_HL_PRTC_CTRL, val);
}
EXPORT_SYMBOL(b53_enable_mcast_snooping);
static void b53_enable_cpu_port(struct b53_device *dev, int port)
{
u8 port_ctrl;
@ -1387,10 +1334,6 @@ static int b53_setup(struct dsa_switch *ds)
b53_disable_port(ds, port);
}
ret = b53_enable_mcast_snooping(dev);
if (ret)
return ret;
return b53_setup_devlink_resources(ds);
}
@ -1720,15 +1663,9 @@ static void b53_phylink_mac_link_up(struct phylink_config *config,
}
if (mode == MLO_AN_FIXED) {
/* Force flow control and 2Gbits/sec on BCM5301x and NSP CPU
* ports
*/
if ((is5301x(dev) || dev->chip_id == BCM58XX_DEVICE_ID) &&
dsa_is_cpu_port(ds, port)) {
tx_pause = true;
rx_pause = true;
speed = 2000;
}
/* Force flow control on BCM5301x's CPU port */
if (is5301x(dev) && dsa_is_cpu_port(ds, port))
tx_pause = rx_pause = true;
b53_force_port_config(dev, port, speed, duplex,
tx_pause, rx_pause);

View File

@ -504,7 +504,6 @@ static inline struct gpio_desc *b53_switch_get_reset_gpio(struct b53_device *dev
/* Exported functions towards other drivers */
void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port);
int b53_configure_vlan(struct dsa_switch *ds);
int b53_enable_mcast_snooping(struct b53_device *dev);
void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset,
uint8_t *data);
void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);

View File

@ -274,23 +274,6 @@
/* Revision ID register (8 bit) */
#define B53_REV_ID 0x40
/* High-level protocol control (16 bit on BCM5395, otherwise 32 bit) */
#define B53_HL_PRTC_CTRL 0x50
#define HL_PRTC_ICMPV6_EN BIT(4)
#define HL_PRTC_ICMPV6_FWD_MODE BIT(5)
#define HL_PRTC_IGMP_IP_EN_5395 BIT(6)
#define HL_PRTC_IGMP_FWD_MODE_5395 BIT(8)
#define HL_PRTC_IGMP_RPTLVE_EN BIT(9)
#define HL_PRTC_IGMP_RPTLVE_FWD_MODE BIT(10)
#define HL_PRTC_IGMP_QRY_EN BIT(11)
#define HL_PRTC_IGMP_QRY_FWD_MODE BIT(12)
#define HL_PRTC_IGMP_UKN_EN BIT(13)
#define HL_PRTC_IGMP_UKN_FWD_MODE BIT(14)
#define HL_PRTC_MLD_RPTDONE_EN BIT(15)
#define HL_PRTC_MLD_RPTDONE_FWD_MODE BIT(16)
#define HL_PRTC_MLD_QRY_EN BIT(17)
#define HL_PRTC_MLD_QRY_FWD_MODE BIT(18)
/* Broadcom header RX control (16 bit) */
#define B53_BRCM_HDR_RX_DIS 0x60

View File

@ -1059,7 +1059,6 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
unsigned int port;
int ret;
/* Enable all valid ports and disable those unused */
for (port = 0; port < priv->hw_params.num_ports; port++) {
@ -1075,10 +1074,6 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
b53_configure_vlan(ds);
bcm_sf2_enable_acb(ds);
ret = b53_enable_mcast_snooping(priv->dev);
if (ret)
return ret;
return b53_setup_devlink_resources(ds);
}

View File

@ -1934,39 +1934,6 @@ static int atl1c_clean_rx(struct napi_struct *napi, int budget)
break;
}
atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
/* A link partner whose l2mtu is larger than ours can hand us a
* frame that does not fit the buffer the hardware was given:
* the descriptor reports the untruncated length while at most
* buffer_info->length bytes were written. skb_put() of such a
* length would pull in whatever the tail of the buffer holds
* and, past the end of the skb, trips skb_over_panic and takes
* the host down. Bound it by what the device actually wrote
* rather than by skb_tailroom(): the skb carries 64 bytes of
* slack for the DMA erratum, so the two are not the same.
*
* Frames shorter than an Ethernet header plus its FCS are
* rejected by the same test; before this, a length below
* ETH_FCS_LEN underflowed in skb_put().
*/
if (unlikely(length < ETH_HLEN + ETH_FCS_LEN ||
length > buffer_info->length)) {
dev_core_stats_rx_dropped_inc(netdev);
if (netif_msg_rx_err(adapter))
dev_warn_ratelimited(&pdev->dev,
"dropped rx frame: %u bytes, buffer %u\n",
length, buffer_info->length);
kfree_skb_reason(skb, SKB_DROP_REASON_PKT_TOO_BIG);
/* atl1c_clean_rfd() has already recycled the RFD, so
* count the drop as work: the refill at the end of the
* poll only runs when work_done is non-zero, and
* sustained oversized traffic would otherwise drain the
* ring and stop RX for good.
*/
work_done++;
continue;
}
skb_put(skb, length - ETH_FCS_LEN);
skb->protocol = eth_type_trans(skb, netdev);
atl1c_rx_checksum(adapter, skb, rrs);

View File

@ -243,8 +243,7 @@ static int bgmac_probe(struct platform_device *pdev)
bgmac->phy_connect = platform_phy_connect;
} else {
bgmac->phy_connect = bgmac_phy_connect_direct;
if (of_machine_is_compatible("brcm,nsp"))
bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
}
return bgmac_enet_probe(bgmac);

View File

@ -1430,15 +1430,11 @@ void bgmac_adjust_link(struct net_device *net_dev)
{
struct bgmac *bgmac = netdev_priv(net_dev);
struct phy_device *phy_dev = net_dev->phydev;
int speed = phy_dev->speed;
bool update = false;
if (bgmac->feature_flags & BGMAC_FEAT_FORCE_SPEED_2500)
speed = SPEED_2500;
if (phy_dev->link) {
if (speed != bgmac->mac_speed) {
bgmac->mac_speed = speed;
if (phy_dev->speed != bgmac->mac_speed) {
bgmac->mac_speed = phy_dev->speed;
update = true;
}

View File

@ -11544,7 +11544,6 @@ static int bnxt_change_msix(struct bnxt *bp, int total)
map.index = i - 1;
map.virq = bp->irq_tbl[i - 1].vector;
pci_msix_free_irq(bp->pdev, map);
bp->irq_tbl[i - 1].vector = 0;
bp->total_irqs--;
}
return bp->total_irqs;
@ -11722,23 +11721,8 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init)
int irqs_required;
int rc;
if (!bnxt_need_reserve_rings(bp)) {
/* FW may already hold the reservation from an earlier
* reservation that was not followed by growing the dynamic
* MSI-X vectors, e.g. because the allocation failed.
*/
if (irq_re_init && BNXT_NEW_RM(bp) && bp->irq_tbl &&
pci_msix_can_alloc_dyn(bp->pdev)) {
irqs_required = bnxt_get_num_msix(bp);
if (irqs_required > bp->total_irqs &&
bnxt_change_msix(bp, irqs_required) != irqs_required) {
netdev_err(bp->dev, "Unable to allocate %d MSIX vectors, maximum available %d\n",
irqs_required, bp->total_irqs);
return -ENOSPC;
}
}
if (!bnxt_need_reserve_rings(bp))
return 0;
}
if (BNXT_NEW_RM(bp) && !bnxt_ulp_registered(edev)) {
int ulp_msix = bnxt_get_avail_msix(bp, bp->ulp_num_msix_want);
@ -11764,10 +11748,6 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init)
rc = bnxt_init_int_mode(bp);
bnxt_ulp_irq_restart(bp, rc);
} else if (irq_change && !rc) {
/* Size the vectors from what FW actually reserved, which
* can be less than what was requested.
*/
irqs_required = bnxt_get_num_msix(bp);
if (bnxt_change_msix(bp, irqs_required) != irqs_required)
rc = -ENOSPC;
}
@ -15133,7 +15113,6 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
hwr.cp = min_t(int, hwr.cp, bnxt_get_max_func_irqs(bp));
}
if (hwr.cp > bp->total_irqs) {
int old_total = bp->total_irqs;
int total_msix = bnxt_change_msix(bp, hwr.cp);
if (total_msix < hwr.cp) {
@ -15141,17 +15120,6 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
hwr.cp, total_msix);
rc = -ENOSPC;
}
/* FW has not reserved the new vectors yet, and writes to
* MSI-X table entries beyond the reserved IRQs don't
* stick (seen on BCM57508). Free them again;
* bnxt_reserve_rings() allocates them after
* __bnxt_reserve_rings(). Without the new resource
* manager there is no IRQ reservation and
* bnxt_reserve_rings() does not grow the vectors, so
* keep them.
*/
if (BNXT_NEW_RM(bp))
bnxt_change_msix(bp, old_total);
}
}
return rc;

View File

@ -1502,8 +1502,7 @@ jme_intr_msi(struct jme_adapter *jme, u32 intrstat)
* all other events are ignored
*/
jwrite32(jme, JME_IEVE, intrstat);
if (!test_bit(JME_FLAG_WOL_QUIESCE, &jme->flags))
schedule_work(&jme->linkch_task);
schedule_work(&jme->linkch_task);
goto out_reenable;
}
@ -1547,8 +1546,7 @@ jme_intr_msi(struct jme_adapter *jme, u32 intrstat)
/*
* Re-enable interrupt
*/
if (!test_bit(JME_FLAG_WOL_QUIESCE, &jme->flags))
jwrite32f(jme, JME_IENS, INTR_ENABLE);
jwrite32f(jme, JME_IENS, INTR_ENABLE);
}
static irqreturn_t
@ -1894,7 +1892,6 @@ jme_powersave_phy(struct jme_adapter *jme)
jme_set_100m_half(jme);
if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
jme_wait_link(jme);
jme_mac_rxclk_on(jme);
jme_clear_pm_enable_wol(jme);
} else {
jme_phy_off(jme);
@ -3161,21 +3158,6 @@ jme_shutdown(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct jme_adapter *jme = netdev_priv(netdev);
if (netif_running(netdev)) {
set_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
netif_device_detach(netdev);
netif_stop_queue(netdev);
jme_stop_irq(jme);
synchronize_irq(pdev->irq);
jme_stop_irq(jme);
cancel_work_sync(&jme->linkch_task);
tasklet_disable(&jme->pcc_task);
napi_disable(&jme->napi);
tasklet_disable(&jme->txclean_task);
tasklet_disable(&jme->rxclean_task);
tasklet_disable(&jme->rxempty_task);
}
jme_powersave_phy(jme);
pci_pme_active(pdev, true);
}
@ -3190,16 +3172,11 @@ jme_suspend(struct device *dev)
if (!netif_running(netdev))
return 0;
set_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
atomic_dec(&jme->link_changing);
netif_device_detach(netdev);
netif_stop_queue(netdev);
jme_stop_irq(jme);
synchronize_irq(jme->pdev->irq);
jme_stop_irq(jme);
cancel_work_sync(&jme->linkch_task);
tasklet_disable(&jme->pcc_task);
napi_disable(&jme->napi);
atomic_dec(&jme->link_changing);
tasklet_disable(&jme->txclean_task);
tasklet_disable(&jme->rxclean_task);
@ -3238,7 +3215,6 @@ jme_resume(struct device *dev)
return 0;
jme_clear_pm_disable_wol(jme);
jme_mac_rxclk_off(jme);
jme_phy_on(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
jme_set_link_ksettings(netdev, &jme->old_cmd);
@ -3250,11 +3226,8 @@ jme_resume(struct device *dev)
atomic_inc(&jme->link_changing);
napi_enable(&jme->napi);
tasklet_enable(&jme->pcc_task);
clear_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
jme_reset_link(jme);
jme_start_irq(jme);
return 0;

View File

@ -450,7 +450,6 @@ enum jme_flags_bits {
JME_FLAG_SSET = 2,
JME_FLAG_POLL = 5,
JME_FLAG_SHUTDOWN = 6,
JME_FLAG_WOL_QUIESCE = 7,
};
#define TX_TIMEOUT (5 * HZ)

View File

@ -754,7 +754,8 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
hlist_for_each_entry_safe(entry, n, head, list) {
if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) {
if (entry->hash != hash)
if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) ==
MTK_FOE_STATE_BIND))
continue;
entry->hash = 0xffff;
@ -763,7 +764,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
}
if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) {
if (entry->hash == hash)
if (entry->hash != 0xffff)
entry->hash = 0xffff;
continue;
}

View File

@ -257,7 +257,7 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
if (!dev->rx_wdma[i].desc)
if (dev->rx_wdma[i].desc)
continue;
wdma_w32(dev,
@ -949,14 +949,6 @@ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
static void
mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
{
int i;
for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++)
mtk_wed_free_ring(dev, &dev->rx_ring[i]);
for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
mtk_wed_free_ring(dev, &dev->tx_wdma[i]);
mtk_wed_free_rx_buffer(dev);
mtk_wed_free_ring(dev, &dev->rro.ring);
}
@ -1946,7 +1938,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
if (!mtk_wed_is_v3_or_greater(dev->hw) && reset)
if (reset)
mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true);
if (!idx) {
@ -2345,20 +2337,7 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
if (!dev->rx_wdma[i].desc)
if (mtk_wed_wdma_rx_ring_setup(dev, i, 16, false)) {
dev_err(dev->hw->dev, "wdma rx ring %d setup failed\n", i);
return;
}
/*
* non-DBDC MT7986 allocates only rx_ring[1] and tx_wdma[1] during setup
* but tx_wdma[0] is also needed for WED to function.
*/
if (mtk_wed_is_v2(dev->hw) && !dev->rx_ring[0].desc)
if (mtk_wed_wdma_tx_ring_setup(dev, 0, MTK_WED_WDMA_RING_SIZE, !!dev->tx_wdma[0].desc)) {
dev_err(dev->hw->dev, "wdma tx ring 0 setup failed\n");
return;
}
mtk_wed_wdma_rx_ring_setup(dev, i, 16, false);
if (dev->wlan.hw_rro) {
for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) {

View File

@ -94,7 +94,6 @@ struct mlx5_fs_id {
refcount_t refcnt;
sci_t sci;
struct rhash_head hash;
struct rcu_head rcu;
};
struct mlx5_macsec_device {
@ -685,7 +684,7 @@ static void macsec_fs_id_del(struct list_head *macsec_devices_list, u32 fs_id,
xa_erase(fs_id_xa, fs_id);
kfree_rcu(fs_id_found, rcu);
kfree(fs_id_found);
if (macsec_fs_is_macsec_device_empty(macsec_device)) {
list_del(&macsec_device->macsec_devices_list_entry);

View File

@ -2072,7 +2072,7 @@ static int fbnic_alloc_rx_qt_resources(struct fbnic_net *fbn,
fbnic_bdq_set_page_size(&qt->sub1, rx_page_size);
err = xdp_rxq_info_reg(&qt->xdp_rxq, fbn->netdev, qt->cmpl.q_idx,
err = xdp_rxq_info_reg(&qt->xdp_rxq, fbn->netdev, qt->sub0.q_idx,
nv->napi.napi_id);
if (err)
goto free_page_pools;

View File

@ -353,12 +353,6 @@ static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
if (!fdma_db_is_done(db))
continue;
/* XDP and page pool APIs can't be used with a budget of 0.
* Leave these buffers for the next NAPI poll.
*/
if (!weight && !dcb_buf->use_skb)
continue;
dcb_buf->dev->stats.tx_packets++;
dcb_buf->dev->stats.tx_bytes += dcb_buf->len;

View File

@ -204,10 +204,9 @@ static void sparx5_ptp_classify(struct sparx5_port *port, struct sk_buff *skb,
*rew_op = IFH_REW_OP_TWO_STEP_PTP;
}
static unsigned int sparx5_ptp_txtstamp_old_release(struct sparx5_port *port)
static void sparx5_ptp_txtstamp_old_release(struct sparx5_port *port)
{
struct sk_buff *skb, *skb_tmp;
unsigned int purged = 0;
unsigned long flags;
spin_lock_irqsave(&port->tx_skbs.lock, flags);
@ -218,11 +217,8 @@ static unsigned int sparx5_ptp_txtstamp_old_release(struct sparx5_port *port)
__skb_unlink(skb, &port->tx_skbs);
dev_kfree_skb_any(skb);
purged++;
}
spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
return purged;
}
int sparx5_ptp_txtstamp_request(struct sparx5_port *port,
@ -230,7 +226,6 @@ int sparx5_ptp_txtstamp_request(struct sparx5_port *port,
{
struct sparx5 *sparx5 = port->sparx5;
u8 rew_op, pdu_type, pdu_w16_offset;
unsigned int purged;
unsigned long flags;
sparx5_ptp_classify(port, skb, &rew_op, &pdu_type, &pdu_w16_offset);
@ -241,10 +236,9 @@ int sparx5_ptp_txtstamp_request(struct sparx5_port *port,
if (rew_op != IFH_REW_OP_TWO_STEP_PTP)
return 0;
purged = sparx5_ptp_txtstamp_old_release(port);
sparx5_ptp_txtstamp_old_release(port);
spin_lock_irqsave(&sparx5->ptp_ts_id_lock, flags);
sparx5->ptp_skbs -= purged;
if (sparx5->ptp_skbs == SPARX5_MAX_PTP_ID) {
spin_unlock_irqrestore(&sparx5->ptp_ts_id_lock, flags);
return -EBUSY;

View File

@ -757,27 +757,6 @@ void mana_gd_free_service_wq(struct gdma_context *gc)
gc->service_wq = NULL;
}
static void mana_gd_schedule_eq_cqs(struct gdma_queue *eq)
{
struct gdma_context *gc = eq->gdma_dev->gdma_context;
struct gdma_queue *cq;
u8 i;
for (i = 0; i < GDMA_EQ_MAX_CHILD_CQ; i++) {
cq = rcu_dereference(eq->eq.child_cq[i]);
if (!cq)
continue;
if (cq->id >= READ_ONCE(gc->max_num_cqs) ||
!gc->cq_table || gc->cq_table[cq->id] != cq)
continue;
if (cq->cq.callback)
cq->cq.callback(cq->cq.context, cq);
}
}
static void mana_gd_process_eqe(struct gdma_queue *eq)
{
u32 head = eq->head % (eq->queue_size / GDMA_EQE_SIZE);
@ -808,14 +787,6 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)
break;
case GDMA_EQE_THROTTLE:
u64_stats_update_begin(&eq->eq.stats.syncp);
u64_stats_inc(&eq->eq.stats.throttle_count);
u64_stats_update_end(&eq->eq.stats.syncp);
mana_gd_schedule_eq_cqs(eq);
break;
case GDMA_EQE_TEST_EVENT:
gc->test_event_eq_id = eq->id;
complete(&gc->eq_test_event);
@ -1061,8 +1032,6 @@ static int mana_gd_create_eq(struct gdma_dev *gd,
queue->eq.msix_index = INVALID_PCI_MSIX_INDEX;
queue->id = INVALID_QUEUE_ID;
u64_stats_init(&queue->eq.stats.syncp);
log2_num_entries = ilog2(queue->queue_size / GDMA_EQE_SIZE);
if (spec->eq.log2_throttle_limit > log2_num_entries) {
@ -1104,66 +1073,25 @@ static void mana_gd_create_cq(const struct gdma_queue_spec *spec,
struct gdma_queue *queue)
{
u32 log2_num_entries = ilog2(spec->queue_size / GDMA_CQE_SIZE);
struct gdma_queue *parent;
u8 i;
queue->head |= INITIALIZED_OWNER_BIT(log2_num_entries);
parent = spec->cq.parent_eq;
queue->cq.parent = parent;
queue->cq.parent = spec->cq.parent_eq;
queue->cq.context = spec->cq.context;
queue->cq.callback = spec->cq.callback;
if (!parent)
return;
/* For throttled EQE store the child CQ */
for (i = 0; i < GDMA_EQ_MAX_CHILD_CQ; i++) {
if (!rcu_access_pointer(parent->eq.child_cq[i])) {
rcu_assign_pointer(parent->eq.child_cq[i], queue);
return;
}
}
WARN_ONCE(1, "mana: EQ %u has no free child CQ slot\n", parent->id);
}
/* Unlink queue from its parent EQ's child_cq[] and from gc->cq_table[].
*
* Return: true if queue was in the parent EQ's child_cq[]. In that case the
* caller must wait for an RCU grace period before freeing queue, because
* mana_gd_intr() may still be handling a throttle EQE for it.
*/
bool mana_gd_detach_cq(struct gdma_context *gc, struct gdma_queue *queue)
{
struct gdma_queue *eq = queue->cq.parent;
bool attached = false;
u32 id = queue->id;
u8 i;
if (eq) {
for (i = 0; i < GDMA_EQ_MAX_CHILD_CQ; i++) {
if (rcu_access_pointer(eq->eq.child_cq[i]) == queue) {
RCU_INIT_POINTER(eq->eq.child_cq[i], NULL);
attached = true;
}
}
}
/* Check if CQ might have been detached already, only clear if
* it still points to same queue .
*/
if (id < gc->max_num_cqs && READ_ONCE(gc->cq_table[id]) == queue)
WRITE_ONCE(gc->cq_table[id], NULL);
return attached;
}
static void mana_gd_destroy_cq(struct gdma_context *gc,
struct gdma_queue *queue)
{
/* Wait for irq reader holding the cq */
if (mana_gd_detach_cq(gc, queue))
synchronize_net();
u32 id = queue->id;
if (id >= gc->max_num_cqs)
return;
if (!gc->cq_table[id])
return;
gc->cq_table[id] = NULL;
}
int mana_gd_create_hwc_queue(struct gdma_dev *gd,

View File

@ -364,7 +364,7 @@ static void mana_hwc_comp_event(void *ctx, struct gdma_queue *q_self)
completions = hwc_cq->comp_buf;
comp_read = mana_gd_poll_cq(q_self, completions, hwc_cq->queue_depth);
WARN_ON_ONCE(comp_read < 0 || comp_read > hwc_cq->queue_depth);
WARN_ON_ONCE(comp_read <= 0 || comp_read > hwc_cq->queue_depth);
for (i = 0; i < comp_read; ++i) {
comp_data = *(struct hwc_rx_oob *)completions[i].cqe_data;
@ -820,14 +820,9 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
*/
if (gc->max_num_cqs > 0) {
mana_smc_teardown_hwc(&gc->shm_channel, false);
WRITE_ONCE(gc->max_num_cqs, 0);
gc->max_num_cqs = 0;
}
if (hwc->cq)
mana_gd_detach_cq(gc, hwc->cq->gdma_cq);
synchronize_rcu();
if (hwc->txq)
mana_hwc_destroy_wq(hwc, hwc->txq);

View File

@ -2703,7 +2703,6 @@ static void mana_deinit_txq(struct mana_port_context *apc, struct mana_txq *txq)
static void mana_destroy_txq(struct mana_port_context *apc)
{
struct gdma_context *gc = apc->ac->gdma_dev->gdma_context;
struct napi_struct *napi;
int i;
@ -2722,6 +2721,8 @@ static void mana_destroy_txq(struct mana_port_context *apc)
napi_synchronize(napi);
napi_disable_locked(napi);
cancel_work_sync(&apc->tx_qp[i]->tx_cq.dim.work);
netif_napi_del_locked(napi);
apc->tx_qp[i]->txq.napi_initialized = false;
}
/* Forget the SKBs freed without being completed after a drain
@ -2734,18 +2735,6 @@ static void mana_destroy_txq(struct mana_port_context *apc)
if (apc->tx_qp[i]->tx_object != INVALID_MANA_HANDLE)
mana_destroy_wq_obj(apc, GDMA_SQ, apc->tx_qp[i]->tx_object);
if (apc->tx_qp[i]->txq.napi_initialized) {
/* Detach the CQ only after the WQ object is destroyed,
* so a completion EQE that arrives before then still
* finds the CQ in cq_table[] rather than hitting the
* WARN in mana_gd_process_eqe(). One grace period then
* covers both mana_gd_intr() and NAPI users.
*/
mana_gd_detach_cq(gc, apc->tx_qp[i]->tx_cq.gdma_cq);
netif_napi_del_locked(napi);
apc->tx_qp[i]->txq.napi_initialized = false;
}
mana_deinit_cq(apc, &apc->tx_qp[i]->tx_cq);
mana_deinit_txq(apc, &apc->tx_qp[i]->txq);
@ -2952,6 +2941,7 @@ static void mana_destroy_rxq(struct mana_port_context *apc,
napi_disable_locked(napi);
cancel_work_sync(&rxq->rx_cq.dim.work);
netif_napi_del_locked(napi);
}
if (xdp_rxq_info_is_reg(&rxq->xdp_rxq))
@ -2960,12 +2950,6 @@ static void mana_destroy_rxq(struct mana_port_context *apc,
if (rxq->rxobj != INVALID_MANA_HANDLE)
mana_destroy_wq_obj(apc, GDMA_RQ, rxq->rxobj);
if (napi_initialized) {
/* See the comment in mana_destroy_txq() */
mana_gd_detach_cq(gc, rxq->rx_cq.gdma_cq);
netif_napi_del_locked(napi);
}
mana_deinit_cq(apc, &rxq->rx_cq);
if (rxq->xdp_save_va)

View File

@ -147,8 +147,7 @@ static int mana_get_sset_count(struct net_device *ndev, int stringset)
return ARRAY_SIZE(mana_eth_stats) +
ARRAY_SIZE(mana_phy_stats) +
ARRAY_SIZE(mana_hc_stats) +
num_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT +
MANA_STATS_EQ_COUNT);
num_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT);
case ETH_SS_PRIV_FLAGS:
return MANA_PRIV_FLAG_MAX;
@ -199,9 +198,6 @@ static void mana_get_strings_stats(struct mana_port_context *apc, u8 **data)
ethtool_sprintf(data, "tx_%d_csum_partial", i);
ethtool_sprintf(data, "tx_%d_mana_map_err", i);
}
for (i = 0; i < num_queues; i++)
ethtool_sprintf(data, "eq_%d_throttle_events", i);
}
static void mana_get_strings_priv_flags(u8 **data)
@ -238,7 +234,6 @@ static void mana_get_ethtool_stats(struct net_device *ndev,
void *phy_stats = &apc->phy_stats;
struct mana_stats_rx *rx_stats;
struct mana_stats_tx *tx_stats;
struct gdma_eq_stats *eq_stats;
unsigned int start;
u64 packets, bytes;
u64 xdp_redirect;
@ -256,7 +251,6 @@ static void mana_get_ethtool_stats(struct net_device *ndev,
u64 csum_partial;
u64 mana_map_err;
int q, i = 0, j;
u64 throttled;
if (!apc->port_is_up)
return;
@ -331,17 +325,6 @@ static void mana_get_ethtool_stats(struct net_device *ndev,
data[i++] = csum_partial;
data[i++] = mana_map_err;
}
for (q = 0; q < num_queues; q++) {
eq_stats = &apc->eqs[q].eq->eq.stats;
do {
start = u64_stats_fetch_begin(&eq_stats->syncp);
throttled = u64_stats_read(&eq_stats->throttle_count);
} while (u64_stats_fetch_retry(&eq_stats->syncp, start));
data[i++] = throttled;
}
}
static u32 mana_get_rx_ring_count(struct net_device *ndev)

View File

@ -600,11 +600,11 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
goto out_unlock;
}
if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) {
cpw16_f(IntrMask, cp_norx_intr_mask);
if (napi_schedule_prep(&cp->napi))
if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
if (napi_schedule_prep(&cp->napi)) {
cpw16_f(IntrMask, cp_norx_intr_mask);
__napi_schedule(&cp->napi);
}
}
if (status & (TxOK | TxErr | TxEmpty | SWInt))
cp_tx(cp);

View File

@ -36,7 +36,6 @@
#include <linux/errno.h>
#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pps_kernel.h>
#include <linux/ptp_clock_kernel.h>
#include "net_driver.h"
@ -267,12 +266,11 @@ struct efx_ptp_rxfilter {
* @evt_frag_idx: Current fragment number
* @evt_code: Last event code
* @start: Address at which MC indicates ready for synchronisation
* @host_time_pps: Host time at last PPS
* @adjfreq_ppb_shift: Shift required to convert scaled parts-per-billion
* frequency adjustment into a fixed point fractional nanosecond format.
* @current_adjfreq: Current ppb adjustment.
* @phc_clock: Pointer to registered phc device (if primary function)
* @phc_lock: Serializes PHC commands and synchronization, and protects
* @current_adjfreq
* @phc_clock_info: Registration structure for phc device
* @pps_work: pps work task for handling pps events
* @pps_workwq: pps work queue
@ -328,10 +326,10 @@ struct efx_ptp_data {
int evt_frag_idx;
int evt_code;
struct efx_buffer start;
struct pps_event_time host_time_pps;
unsigned int adjfreq_ppb_shift;
s64 current_adjfreq;
struct ptp_clock *phc_clock;
struct mutex phc_lock;
struct ptp_clock_info phc_clock_info;
struct work_struct pps_work;
struct workqueue_struct *pps_workwq;
@ -909,8 +907,7 @@ static void efx_ptp_read_timeset(MCDI_DECLARE_STRUCT_PTR(data),
static int
efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
size_t response_length,
const struct pps_event_time *last_time,
struct pps_event_time *host_time_pps)
const struct pps_event_time *last_time)
{
unsigned number_readings =
MCDI_VAR_ARRAY_LEN(response_length,
@ -988,10 +985,6 @@ efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
"PTP bad synchronisation seconds\n");
return -EAGAIN;
}
if (!host_time_pps)
return 0;
delta.tv_sec = (last_sec - start_sec) & 1;
delta.tv_nsec =
last_time->ts_real.tv_nsec -
@ -1008,22 +1001,14 @@ efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
delta.tv_nsec += ktime_to_timespec64(mc_time).tv_nsec;
/* Set PPS timestamp to match NIC top of second */
*host_time_pps = *last_time;
pps_sub_ts(host_time_pps, delta);
ptp->host_time_pps = *last_time;
pps_sub_ts(&ptp->host_time_pps, delta);
return 0;
}
/* Synchronize times between the host and the MC.
*
* The MC serializes PTP requests, so MC_CMD_PTP_OP_ADJUST cannot be applied
* while MC_CMD_PTP_OP_SYNCHRONIZE is collecting timesets. This holds across
* functions of a controller, which share the clock but adjust it only through
* the function that registered it, so a secondary function can capture here
* without serializing against the primary.
*/
static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings,
struct pps_event_time *host_time_pps)
/* Synchronize times between the host and the MC */
static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings)
{
struct efx_ptp_data *ptp = efx->ptp_data;
MCDI_DECLARE_BUF(synch_buf, MC_CMD_PTP_OUT_SYNCHRONIZE_LENMAX);
@ -1041,14 +1026,11 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings,
MCDI_SET_QWORD(synch_buf, PTP_IN_SYNCHRONIZE_START_ADDR,
ptp->start.dma_addr);
mutex_lock(&ptp->phc_lock);
/* Clear flag that signals MC ready */
WRITE_ONCE(*start, 0);
rc = efx_mcdi_rpc_start(efx, MC_CMD_PTP, synch_buf,
MC_CMD_PTP_IN_SYNCHRONIZE_LEN);
if (rc)
goto out;
EFX_WARN_ON_ONCE_PARANOID(rc);
/* Wait for start from MCDI (or timeout) */
timeout = jiffies + msecs_to_jiffies(MAX_SYNCHRONISE_WAIT_MS);
@ -1072,20 +1054,18 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings,
&response_length);
if (rc == 0) {
rc = efx_ptp_process_times(efx, synch_buf, response_length,
&last_time, host_time_pps);
&last_time);
if (rc == 0)
++ptp->good_syncs;
else
++ptp->no_time_syncs;
}
out:
/* Increment the bad syncs counter if the synchronize fails, whatever
* the reason.
*/
if (rc != 0)
++ptp->bad_syncs;
mutex_unlock(&ptp->phc_lock);
return rc;
}
@ -1465,6 +1445,7 @@ static int efx_ptp_start(struct efx_nic *efx)
goto fail;
ptp->evt_frag_idx = 0;
ptp->current_adjfreq = 0;
return 0;
@ -1504,15 +1485,14 @@ static void efx_ptp_pps_worker(struct work_struct *work)
{
struct efx_ptp_data *ptp =
container_of(work, struct efx_ptp_data, pps_work);
struct pps_event_time host_time_pps = {};
struct efx_nic *efx = ptp->efx;
struct ptp_clock_event ptp_evt;
if (efx_ptp_synchronize(efx, PTP_SYNC_ATTEMPTS, &host_time_pps))
if (efx_ptp_synchronize(efx, PTP_SYNC_ATTEMPTS))
return;
ptp_evt.type = PTP_CLOCK_PPSUSR;
ptp_evt.pps_times = host_time_pps;
ptp_evt.pps_times = ptp->host_time_pps;
ptp_clock_event(ptp->phc_clock, &ptp_evt);
}
@ -1589,7 +1569,6 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
if (!efx->ptp_data)
return -ENOMEM;
mutex_init(&ptp->phc_lock);
ptp->efx = efx;
ptp->channel = channel;
@ -1661,7 +1640,6 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
efx_nic_free_buffer(efx, &ptp->start);
fail1:
mutex_destroy(&ptp->phc_lock);
kfree(efx->ptp_data);
efx->ptp_data = NULL;
@ -1716,7 +1694,6 @@ void efx_ptp_remove(struct efx_nic *efx)
destroy_workqueue(efx->ptp_data->workwq);
efx_nic_free_buffer(efx, &efx->ptp_data->start);
mutex_destroy(&efx->ptp_data->phc_lock);
kfree(efx->ptp_data);
efx->ptp_data = NULL;
}
@ -1848,8 +1825,7 @@ int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted,
rc = efx_ptp_start(efx);
if (rc == 0) {
rc = efx_ptp_synchronize(efx,
PTP_SYNC_ATTEMPTS * 2,
NULL);
PTP_SYNC_ATTEMPTS * 2);
if (rc != 0)
efx_ptp_stop(efx);
}
@ -2129,23 +2105,23 @@ static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
MCDI_SET_QWORD(inadj, PTP_IN_ADJUST_FREQ, adjustment_ns);
MCDI_SET_DWORD(inadj, PTP_IN_ADJUST_SECONDS, 0);
MCDI_SET_DWORD(inadj, PTP_IN_ADJUST_NANOSECONDS, 0);
mutex_lock(&ptp_data->phc_lock);
rc = efx_mcdi_rpc(efx, MC_CMD_PTP, inadj, sizeof(inadj),
NULL, 0, NULL);
if (!rc)
ptp_data->current_adjfreq = adjustment_ns;
mutex_unlock(&ptp_data->phc_lock);
return rc;
if (rc != 0)
return rc;
ptp_data->current_adjfreq = adjustment_ns;
return 0;
}
static int _efx_phc_adjtime(struct efx_ptp_data *ptp_data, s64 delta)
__must_hold(&ptp_data->phc_lock)
static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ADJUST_LEN);
struct efx_nic *efx = ptp_data->efx;
u32 nic_major, nic_minor;
lockdep_assert_held(&ptp_data->phc_lock);
struct efx_ptp_data *ptp_data = container_of(ptp,
struct efx_ptp_data,
phc_clock_info);
struct efx_nic *efx = ptp_data->efx;
MCDI_DECLARE_BUF(inbuf, MC_CMD_PTP_IN_ADJUST_LEN);
efx->ptp_data->ns_to_nic_time(delta, &nic_major, &nic_minor);
@ -2158,18 +2134,6 @@ static int _efx_phc_adjtime(struct efx_ptp_data *ptp_data, s64 delta)
NULL, 0, NULL);
}
static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct efx_ptp_data *ptp_data = container_of(ptp, struct efx_ptp_data,
phc_clock_info);
int rc;
mutex_lock(&ptp_data->phc_lock);
rc = _efx_phc_adjtime(ptp_data, delta);
mutex_unlock(&ptp_data->phc_lock);
return rc;
}
static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
struct efx_ptp_data *ptp_data = container_of(ptp,
@ -2201,21 +2165,23 @@ static int efx_phc_settime(struct ptp_clock_info *ptp,
{
/* Get the current NIC time, efx_phc_gettime.
* Subtract from the desired time to get the offset
* call _efx_phc_adjtime with the offset
* call efx_phc_adjtime with the offset
*/
struct efx_ptp_data *ptp_data = container_of(ptp, struct efx_ptp_data,
phc_clock_info);
struct timespec64 time_now, delta;
int rc;
struct timespec64 time_now;
struct timespec64 delta;
mutex_lock(&ptp_data->phc_lock);
rc = efx_phc_gettime(ptp, &time_now);
if (!rc) {
delta = timespec64_sub(*e_ts, time_now);
rc = _efx_phc_adjtime(ptp_data, timespec64_to_ns(&delta));
}
mutex_unlock(&ptp_data->phc_lock);
return rc;
if (rc != 0)
return rc;
delta = timespec64_sub(*e_ts, time_now);
rc = efx_phc_adjtime(ptp, timespec64_to_ns(&delta));
if (rc != 0)
return rc;
return 0;
}
static int efx_phc_enable(struct ptp_clock_info *ptp,

View File

@ -205,7 +205,7 @@ static int enh_desc_get_rx_status(struct stmmac_extra_stats *x,
if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) {
x->rx_length++;
return discard_frame | rx_not_ls;
return discard_frame;
}
if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) {

View File

@ -620,7 +620,7 @@ struct stmmac_mmc_ops {
struct stmmac_est_ops {
int (*configure)(struct stmmac_priv *priv, struct stmmac_est *cfg,
unsigned int ptp_rate, bool enable);
unsigned int ptp_rate);
void (*irq_status)(struct stmmac_priv *priv, struct net_device *dev,
struct stmmac_extra_stats *x, u32 txqcnt);
};

View File

@ -70,7 +70,7 @@ static int ndesc_get_rx_status(struct stmmac_extra_stats *x,
if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) {
x->rx_length++;
return discard_frame | rx_not_ls;
return discard_frame;
}
if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) {

View File

@ -239,7 +239,6 @@ struct stmmac_est {
u32 gcl[EST_GCL];
u32 gcl_size;
u32 max_sdu[MTL_MAX_TX_QUEUES];
u32 pclass;
};
struct stmmac_msi {

View File

@ -26,7 +26,7 @@ static int est_write(void __iomem *est_addr, u32 reg, u32 val, bool gcl)
}
static int est_configure(struct stmmac_priv *priv, struct stmmac_est *cfg,
unsigned int ptp_rate, bool enable)
unsigned int ptp_rate)
{
void __iomem *est_addr = priv->estaddr;
int i, ret = 0;
@ -62,7 +62,7 @@ static int est_configure(struct stmmac_priv *priv, struct stmmac_est *cfg,
ctrl |= ((NSEC_PER_SEC / ptp_rate) * EST_GMAC5_PTOV_MUL) <<
EST_GMAC5_PTOV_SHIFT;
}
if (enable)
if (cfg->enable)
ctrl |= EST_EEST | EST_SSWL | EST_DFBS;
else
ctrl &= ~EST_EEST;
@ -70,7 +70,7 @@ static int est_configure(struct stmmac_priv *priv, struct stmmac_est *cfg,
writel(ctrl, est_addr + EST_CONTROL);
/* Configure EST interrupt */
if (enable)
if (cfg->enable)
ctrl = EST_IECGCE | EST_IEHS | EST_IEHF | EST_IEBE | EST_IECC;
else
ctrl = 0;
@ -80,61 +80,6 @@ static int est_configure(struct stmmac_priv *priv, struct stmmac_est *cfg,
return 0;
}
int __stmmac_setup_est(struct stmmac_priv *priv)
{
struct timespec64 current_time, time;
ktime_t current_time_ns, basetime;
u64 cycle_time;
int err;
lockdep_assert_held(&priv->est_lock);
priv->ptp_clock_ops.gettimex64(&priv->ptp_clock_ops, &current_time,
NULL);
current_time_ns = timespec64_to_ktime(current_time);
time.tv_nsec = priv->est->btr_reserve[0];
time.tv_sec = priv->est->btr_reserve[1];
basetime = timespec64_to_ktime(time);
cycle_time = (u64)priv->est->ctr[1] * NSEC_PER_SEC + priv->est->ctr[0];
time = stmmac_calc_tas_basetime(basetime, current_time_ns, cycle_time);
priv->est->btr[0] = (u32)time.tv_nsec;
priv->est->btr[1] = (u32)time.tv_sec;
err = stmmac_est_configure(priv, priv, priv->est,
priv->plat->clk_ptp_rate, true);
if (err) {
netdev_err(priv->dev, "failed to re-configure EST\n");
return err;
}
return 0;
}
int stmmac_setup_est(struct stmmac_priv *priv)
{
int ret = 0;
if (!priv->ptp_enabled)
return 0;
mutex_lock(&priv->est_lock);
if (priv->est && priv->est->enable) {
ret = __stmmac_setup_est(priv);
if (ret)
goto unlock;
ret = stmmac_fpe_map_preemption_class(priv, priv->dev, NULL,
priv->est->pclass);
}
unlock:
mutex_unlock(&priv->est_lock);
return ret;
}
static void est_irq_status(struct stmmac_priv *priv, struct net_device *dev,
struct stmmac_extra_stats *x, u32 txqcnt)
{

View File

@ -4,9 +4,6 @@
* stmmac EST(802.3 Qbv) handling
*/
#ifndef __STMMAC_EST_H__
#define __STMMAC_EST_H__
#define EST_GMAC4_OFFSET 0x00000c50
#define EST_XGMAC_OFFSET 0x00001050
@ -68,8 +65,3 @@
#define EST_GCL_DATA 0x00000034
extern const struct stmmac_est_ops dwmac510_est_ops;
int __stmmac_setup_est(struct stmmac_priv *priv);
int stmmac_setup_est(struct stmmac_priv *priv);
#endif /* __STMMAC_EST_H__ */

View File

@ -48,7 +48,6 @@
#include "stmmac_ptp.h"
#include "stmmac_fpe.h"
#include "stmmac.h"
#include "stmmac_est.h"
#include "stmmac_pcs.h"
#include "stmmac_xdp.h"
#include <linux/reset.h>
@ -2183,9 +2182,6 @@ static void __free_dma_rx_desc_resources(struct stmmac_priv *priv,
else
dma_free_rx_skbufs(priv, dma_conf, queue);
dev_kfree_skb_any(rx_q->state.skb);
rx_q->state.skb = NULL;
rx_q->state_saved = false;
rx_q->buf_alloc_num = 0;
rx_q->xsk_pool = NULL;
@ -4205,10 +4201,6 @@ static int __stmmac_open(struct net_device *dev,
if (ret)
goto ptp_error;
ret = stmmac_setup_est(priv);
if (ret)
goto est_error;
stmmac_init_coalesce(priv);
phylink_start(priv->phylink);
@ -4232,7 +4224,7 @@ static int __stmmac_open(struct net_device *dev,
for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
est_error:
stmmac_release_ptp(priv);
ptp_error:
stmmac_stop_all_dma(priv);
@ -5107,35 +5099,22 @@ static netdev_features_t stmmac_features_check(struct sk_buff *skb,
return vlan_features_check(skb, features);
}
static int stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb)
static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb)
{
struct vlan_ethhdr *veth;
struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb);
__be16 vlan_proto = veth->h_vlan_proto;
u16 vlanid;
if (!pskb_may_pull(skb, ETH_HLEN))
return -EINVAL;
veth = skb_vlan_eth_hdr(skb);
if ((veth->h_vlan_proto == htons(ETH_P_8021Q) &&
if ((vlan_proto == htons(ETH_P_8021Q) &&
dev->features & NETIF_F_HW_VLAN_CTAG_RX) ||
(veth->h_vlan_proto == htons(ETH_P_8021AD) &&
(vlan_proto == htons(ETH_P_8021AD) &&
dev->features & NETIF_F_HW_VLAN_STAG_RX)) {
__be16 vlan_proto = veth->h_vlan_proto;
u8 meta_len = skb_metadata_len(skb);
u16 vlanid;
/* pop the vlan tag */
if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
return -EINVAL;
veth = skb_vlan_eth_hdr(skb);
vlanid = ntohs(veth->h_vlan_TCI);
memmove(skb->data - meta_len + VLAN_HLEN,
skb->data - meta_len, meta_len + ETH_ALEN * 2);
memmove(skb->data + VLAN_HLEN, veth, ETH_ALEN * 2);
skb_pull(skb, VLAN_HLEN);
__vlan_hwaccel_put_tag(skb, vlan_proto, vlanid);
}
return 0;
}
static bool stmmac_rx_need_ic(struct stmmac_priv *priv,
@ -5537,8 +5516,7 @@ static struct sk_buff *stmmac_construct_skb_zc(struct stmmac_channel *ch,
return NULL;
skb_reserve(skb, xdp->data - xdp->data_hard_start);
__skb_put(skb, datasize);
memcpy(skb->data - metasize, xdp->data_meta, datasize + metasize);
memcpy(__skb_put(skb, datasize), xdp->data, datasize);
if (metasize)
skb_metadata_set(skb, metasize);
@ -5564,15 +5542,12 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
}
stmmac_get_rx_hwtstamp(priv, p, np, skb);
if (priv->hw->hw_vlan_en) {
if (priv->hw->hw_vlan_en)
/* MAC level stripping. */
stmmac_rx_hw_vlan(priv, priv->hw, p, skb);
} else if (stmmac_rx_vlan(priv->dev, skb)) {
dev_kfree_skb_any(skb);
priv->xstats.rx_dropped++;
return;
}
else
/* Driver level stripping. */
stmmac_rx_vlan(priv->dev, skb);
skb->protocol = eth_type_trans(skb, priv->dev);
if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
@ -5654,12 +5629,12 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
unsigned int count = 0, error = 0, len = 0;
int dirty = stmmac_rx_dirty(priv, queue);
unsigned int next_entry = rx_q->cur_rx;
bool in_progress = rx_q->state_saved;
u32 rx_errors = 0, rx_dropped = 0;
unsigned int desc_size;
struct bpf_prog *prog;
bool failure = false;
int xdp_status = 0;
int status = 0;
if (netif_msg_rx_status(priv)) {
void *rx_head = stmmac_get_rx_desc(priv, rx_q, 0);
@ -5670,25 +5645,23 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
stmmac_display_ring(priv, rx_head, priv->dma_conf.dma_rx_size, true,
rx_q->dma_rx_phy, desc_size);
}
if (rx_q->state_saved) {
error = rx_q->state.error;
len = rx_q->state.len;
rx_q->state_saved = false;
}
while (count < limit) {
struct stmmac_rx_buffer *buf;
struct stmmac_xdp_buff *ctx;
unsigned int buf1_len = 0;
struct dma_desc *np, *p;
int entry, status;
int entry;
int res;
if (!in_progress) {
if (!count && rx_q->state_saved) {
error = rx_q->state.error;
len = rx_q->state.len;
} else {
rx_q->state_saved = false;
error = 0;
len = 0;
}
read_again:
if (count >= limit)
break;
@ -5727,8 +5700,6 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
if (!buf->xdp)
break;
in_progress = status & rx_not_ls;
if (priv->extend_desc) {
/* Read the extended status after the own bit */
dma_rmb();
@ -5736,21 +5707,18 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
&rx_q->dma_erx[entry],
status);
}
if (unlikely(!error && (status & discard_frame))) {
if (unlikely(status == discard_frame)) {
xsk_buff_free(buf->xdp);
buf->xdp = NULL;
dirty++;
error = 1;
if (!priv->hwts_rx_en)
rx_errors++;
}
if (unlikely(error && (status & rx_not_ls)))
goto read_again;
if (unlikely(error)) {
xsk_buff_free(buf->xdp);
buf->xdp = NULL;
dirty++;
if (status & rx_not_ls)
goto read_again;
count++;
continue;
}
@ -5759,9 +5727,8 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
if (likely(status & rx_not_ls)) {
xsk_buff_free(buf->xdp);
buf->xdp = NULL;
rx_dropped++;
error = 1;
dirty++;
count++;
goto read_again;
}
@ -5809,7 +5776,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
count++;
}
if (in_progress) {
if (status & rx_not_ls) {
rx_q->state_saved = true;
rx_q->state.error = error;
rx_q->state.len = len;
@ -5851,10 +5818,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
struct stmmac_channel *ch = &priv->channel[queue];
unsigned int count = 0, error = 0, len = 0;
int status = 0, coe = priv->hw->rx_csum;
unsigned int next_entry = rx_q->cur_rx;
bool in_progress = rx_q->state_saved;
enum dma_data_direction dma_dir;
int coe = priv->hw->rx_csum;
unsigned int desc_size;
struct sk_buff *skb = NULL;
struct stmmac_xdp_buff ctx;
@ -5874,28 +5840,25 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
stmmac_display_ring(priv, rx_head, priv->dma_conf.dma_rx_size, true,
rx_q->dma_rx_phy, desc_size);
}
if (rx_q->state_saved) {
skb = rx_q->state.skb;
error = rx_q->state.error;
len = rx_q->state.len;
rx_q->state.skb = NULL;
rx_q->state_saved = false;
}
while (count < limit) {
unsigned int buf1_len = 0, buf2_len = 0;
enum pkt_hash_types hash_type;
struct stmmac_rx_buffer *buf;
struct dma_desc *np, *p;
int entry, status;
int entry;
u32 hash;
if (!in_progress) {
if (!count && rx_q->state_saved) {
skb = rx_q->state.skb;
error = rx_q->state.error;
len = rx_q->state.len;
} else {
rx_q->state_saved = false;
skb = NULL;
error = 0;
len = 0;
}
read_again:
if (count >= limit)
break;
@ -5924,8 +5887,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
prefetch(np);
in_progress = status & rx_not_ls;
if (priv->extend_desc) {
/* Read the extended status after the own bit */
dma_rmb();
@ -5933,26 +5894,21 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
&rx_q->dma_erx[entry],
status);
}
if (unlikely(!error && (status & discard_frame))) {
if (unlikely(status == discard_frame)) {
page_pool_put_page(rx_q->page_pool, buf->page, 0, true);
buf->page = NULL;
error = 1;
if (!priv->hwts_rx_en)
rx_errors++;
}
/* We do not support SG in XDP mode */
if (unlikely(!error && (status & rx_not_ls) &&
stmmac_xdp_is_enabled(priv))) {
rx_dropped++;
error = 1;
}
if (unlikely(error && (status & rx_not_ls)))
goto read_again;
if (unlikely(error)) {
if (status & rx_not_ls)
goto read_again;
dev_kfree_skb(skb);
goto next;
skb = NULL;
count++;
continue;
}
/* Buffer is good. Go on. */
@ -5962,19 +5918,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
buf2_len = stmmac_rx_buf2_len(priv, p, status, len);
len += buf2_len;
/* Drop the packet if it is split over buf1 and buf2 on a
* single descriptor if the interface is running in XDP mode.
*/
if (unlikely(stmmac_xdp_is_enabled(priv) && buf2_len)) {
rx_dropped++;
goto next;
}
/* ACS is disabled; strip manually. */
if (likely(!(status & rx_not_ls)))
len -= ETH_FCS_LEN;
if (!skb) {
unsigned int pre_len, sync_len;
/* Each frame starts here: reset the FCS handling */
fcs_stripped = false;
@ -5992,32 +5942,55 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
xdp_prepare_buff(&ctx.xdp, page_address(buf->page),
buf->page_offset, buf1_len, true);
pre_len = ctx.xdp.data_end - ctx.xdp.data_hard_start -
buf->page_offset;
ctx.priv = priv;
ctx.desc = p;
ctx.ndesc = np;
skb = stmmac_xdp_run_prog(priv, &ctx.xdp);
/* Due xdp_adjust_tail: DMA sync for_device
* cover max len CPU touch
*/
sync_len = ctx.xdp.data_end - ctx.xdp.data_hard_start -
buf->page_offset;
sync_len = max(sync_len, pre_len);
/* For Not XDP_PASS verdict */
if (IS_ERR(skb)) {
unsigned int xdp_res = -PTR_ERR(skb);
if (xdp_res & STMMAC_XDP_CONSUMED) {
page_pool_recycle_direct(rx_q->page_pool,
virt_to_head_page(ctx.xdp.data));
page_pool_put_page(rx_q->page_pool,
virt_to_head_page(ctx.xdp.data),
sync_len, true);
buf->page = NULL;
rx_dropped++;
goto next;
/* Clear skb as it was set as
* status by XDP program.
*/
skb = NULL;
if (unlikely((status & rx_not_ls)))
goto read_again;
count++;
continue;
} else if (xdp_res & (STMMAC_XDP_TX |
STMMAC_XDP_REDIRECT)) {
xdp_status |= xdp_res;
buf->page = NULL;
goto next;
skb = NULL;
count++;
continue;
}
}
}
if (!skb) {
unsigned int metasize;
unsigned int head_pad_len;
/* XDP program may expand or reduce tail */
buf1_len = ctx.xdp.data_end - ctx.xdp.data;
@ -6034,14 +6007,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
}
/* XDP program may adjust header */
skb_reserve(skb,
ctx.xdp.data - ctx.xdp.data_hard_start);
head_pad_len = ctx.xdp.data - ctx.xdp.data_hard_start;
skb_reserve(skb, head_pad_len);
skb_put(skb, buf1_len);
skb_mark_for_recycle(skb);
metasize = ctx.xdp.data - ctx.xdp.data_meta;
if (metasize)
skb_metadata_set(skb, metasize);
buf->page = NULL;
} else if (buf1_len) {
dma_sync_single_for_cpu(priv->device, buf->addr,
@ -6072,20 +6041,20 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
/* Remove FCS if needed */
if (!fcs_stripped && pskb_trim(skb, len)) {
dev_kfree_skb_any(skb);
skb = NULL;
rx_dropped++;
goto next;
count++;
continue;
}
stmmac_get_rx_hwtstamp(priv, p, np, skb);
if (priv->hw->hw_vlan_en) {
if (priv->hw->hw_vlan_en)
/* MAC level stripping. */
stmmac_rx_hw_vlan(priv, priv->hw, p, skb);
} else if (stmmac_rx_vlan(priv->dev, skb)) {
dev_kfree_skb_any(skb);
rx_dropped++;
goto next;
}
else
/* Driver level stripping. */
stmmac_rx_vlan(priv->dev, skb);
skb->protocol = eth_type_trans(skb, priv->dev);
@ -6100,15 +6069,14 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
skb_record_rx_queue(skb, queue);
napi_gro_receive(&ch->rx_napi, skb);
skb = NULL;
rx_packets++;
rx_bytes += len;
next:
in_progress = false;
skb = NULL;
count++;
}
if (in_progress || skb) {
if (status & rx_not_ls || skb) {
rx_q->state_saved = true;
rx_q->state.skb = skb;
rx_q->state.error = error;
@ -8245,7 +8213,6 @@ static int __stmmac_dvr_probe(struct device *device,
stmmac_napi_add(ndev);
mutex_init(&priv->lock);
mutex_init(&priv->est_lock);
rwlock_init(&priv->ptp_lock);
stmmac_fpe_init(priv);
@ -8379,7 +8346,6 @@ void stmmac_dvr_remove(struct device *dev)
destroy_workqueue(priv->wq);
mutex_destroy(&priv->lock);
mutex_destroy(&priv->est_lock);
bitmap_free(priv->af_xdp_zc_qps);
pm_runtime_disable(dev);
@ -8455,9 +8421,6 @@ static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue)
{
struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
dev_kfree_skb_any(rx_q->state.skb);
rx_q->state.skb = NULL;
rx_q->state_saved = false;
rx_q->cur_rx = 0;
rx_q->dirty_rx = 0;
}
@ -8562,10 +8525,6 @@ int stmmac_resume(struct device *dev)
ret = stmmac_init_timestamping(priv);
if (ret)
goto error_stop_dma;
ret = stmmac_setup_est(priv);
if (ret)
goto error_stop_dma;
}
init_coalesce:

View File

@ -8,7 +8,6 @@
Author: Rayagond Kokatanur <rayagond@vayavyalabs.com>
*******************************************************************************/
#include "stmmac.h"
#include "stmmac_est.h"
#include "stmmac_ptp.h"
#define PTP_SAFE_TIME_OFFSET_NS 500000
@ -55,7 +54,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
u32 sec, nsec;
u32 quotient, reminder;
int neg_adj = 0;
bool xmac;
bool xmac, est_rst = false;
int ret;
xmac = dwmac_is_xmac(priv->plat->core_type);
@ -69,21 +69,47 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
nsec = reminder;
/* If EST is enabled, disabled it before adjust ptp time. */
mutex_lock(&priv->est_lock);
if (priv->est && priv->est->enable)
if (priv->est && priv->est->enable) {
est_rst = true;
mutex_lock(&priv->est_lock);
priv->est->enable = false;
stmmac_est_configure(priv, priv, priv->est,
priv->plat->clk_ptp_rate, false);
mutex_unlock(&priv->est_lock);
priv->plat->clk_ptp_rate);
mutex_unlock(&priv->est_lock);
}
write_lock_irqsave(&priv->ptp_lock, flags);
stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
write_unlock_irqrestore(&priv->ptp_lock, flags);
/* Calculate new basetime and re-configured EST after PTP time adjust. */
mutex_lock(&priv->est_lock);
if (priv->est && priv->est->enable)
__stmmac_setup_est(priv);
mutex_unlock(&priv->est_lock);
if (est_rst) {
struct timespec64 current_time, time;
ktime_t current_time_ns, basetime;
u64 cycle_time;
mutex_lock(&priv->est_lock);
priv->ptp_clock_ops.gettimex64(&priv->ptp_clock_ops,
&current_time, NULL);
current_time_ns = timespec64_to_ktime(current_time);
time.tv_nsec = priv->est->btr_reserve[0];
time.tv_sec = priv->est->btr_reserve[1];
basetime = timespec64_to_ktime(time);
cycle_time = (u64)priv->est->ctr[1] * NSEC_PER_SEC +
priv->est->ctr[0];
time = stmmac_calc_tas_basetime(basetime,
current_time_ns,
cycle_time);
priv->est->btr[0] = (u32)time.tv_nsec;
priv->est->btr[1] = (u32)time.tv_sec;
priv->est->enable = true;
ret = stmmac_est_configure(priv, priv, priv->est,
priv->plat->clk_ptp_rate);
mutex_unlock(&priv->est_lock);
if (ret)
netdev_err(priv->dev, "failed to configure EST\n");
}
return 0;
}

View File

@ -966,12 +966,11 @@ static void tc_taprio_map_maxsdu_txq(struct stmmac_priv *priv,
static int tc_taprio_configure(struct stmmac_priv *priv,
struct tc_taprio_qopt_offload *qopt)
{
u32 wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep;
u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep;
struct netlink_ext_ack *extack = qopt->mqprio.extack;
struct timespec64 time, current_time, qopt_time;
ktime_t current_time_ns;
int err, i, ret = 0;
u32 *gcl = NULL;
u64 ctr;
if (qopt->base_time < 0)
@ -1014,46 +1013,44 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
return -EOPNOTSUPP;
}
mutex_lock(&priv->est_lock);
if (qopt->cmd == TAPRIO_CMD_DESTROY)
goto disable;
if (qopt->num_entries > dep) {
ret = -EINVAL;
goto error_unlock;
if (qopt->num_entries > dep)
return -EINVAL;
if (!qopt->cycle_time)
return -ERANGE;
if (qopt->cycle_time_extension >= BIT(wid + 7))
return -ERANGE;
if (!priv->est) {
priv->est = devm_kzalloc(priv->device, sizeof(*priv->est),
GFP_KERNEL);
if (!priv->est)
return -ENOMEM;
mutex_init(&priv->est_lock);
} else {
mutex_lock(&priv->est_lock);
memset(priv->est, 0, sizeof(*priv->est));
mutex_unlock(&priv->est_lock);
}
if (!qopt->cycle_time ||
qopt->cycle_time > (u64)U32_MAX * NSEC_PER_SEC) {
ret = -ERANGE;
goto error_unlock;
}
size = qopt->num_entries;
if (qopt->cycle_time_extension >= BIT(wid + 7)) {
ret = -ERANGE;
goto error_unlock;
}
mutex_lock(&priv->est_lock);
priv->est->gcl_size = size;
priv->est->enable = qopt->cmd == TAPRIO_CMD_REPLACE;
mutex_unlock(&priv->est_lock);
gcl = kcalloc(qopt->num_entries, sizeof(*gcl), GFP_KERNEL);
if (!gcl) {
ret = -ENOMEM;
goto error_unlock;
}
for (i = 0; i < qopt->num_entries; i++) {
for (i = 0; i < size; i++) {
s64 delta_ns = qopt->entries[i].interval;
u32 gates = qopt->entries[i].gate_mask;
if (delta_ns > GENMASK(wid - 1, 0)) {
ret = -ERANGE;
goto error_unlock;
}
if (gates > GENMASK(31 - wid, 0)) {
ret = -ERANGE;
goto error_unlock;
}
if (delta_ns > GENMASK(wid - 1, 0))
return -ERANGE;
if (gates > GENMASK(31 - wid, 0))
return -ERANGE;
switch (qopt->entries[i].command) {
case TC_TAPRIO_CMD_SET_GATES:
@ -1065,26 +1062,13 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
gates &= ~BIT(0);
break;
default:
ret = -EOPNOTSUPP;
goto error_unlock;
return -EOPNOTSUPP;
}
gcl[i] = delta_ns | (gates << wid);
priv->est->gcl[i] = delta_ns | (gates << wid);
}
if (!priv->est) {
priv->est = devm_kzalloc(priv->device, sizeof(*priv->est),
GFP_KERNEL);
if (!priv->est) {
ret = -ENOMEM;
goto error_unlock;
}
} else {
memset(priv->est, 0, sizeof(*priv->est));
}
memcpy(priv->est->gcl, gcl, sizeof(*gcl) * qopt->num_entries);
priv->est->gcl_size = qopt->num_entries;
mutex_lock(&priv->est_lock);
/* Adjust for real system time */
priv->ptp_clock_ops.gettimex64(&priv->ptp_clock_ops, &current_time,
NULL);
@ -1108,7 +1092,8 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
tc_taprio_map_maxsdu_txq(priv, qopt);
ret = stmmac_est_configure(priv, priv, priv->est,
priv->plat->clk_ptp_rate, true);
priv->plat->clk_ptp_rate);
mutex_unlock(&priv->est_lock);
if (ret) {
netdev_err(priv->dev, "failed to configure EST\n");
goto disable;
@ -1119,31 +1104,24 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
if (ret)
goto disable;
priv->est->pclass = qopt->mqprio.preemptible_tcs;
priv->est->enable = true;
mutex_unlock(&priv->est_lock);
kfree(gcl);
return 0;
disable:
if (priv->est) {
mutex_lock(&priv->est_lock);
priv->est->enable = false;
stmmac_est_configure(priv, priv, priv->est,
priv->plat->clk_ptp_rate, false);
priv->plat->clk_ptp_rate);
/* Reset taprio status */
for (i = 0; i < priv->plat->tx_queues_to_use; i++) {
priv->xstats.max_sdu_txq_drop[i] = 0;
priv->xstats.mtl_est_txq_hlbf[i] = 0;
priv->xstats.mtl_est_txq_hlbs[i] = 0;
}
mutex_unlock(&priv->est_lock);
}
err = stmmac_fpe_map_preemption_class(priv, priv->dev, extack, 0);
error_unlock:
mutex_unlock(&priv->est_lock);
kfree(gcl);
return qopt->cmd == TAPRIO_CMD_DESTROY ? err : ret;
}

View File

@ -128,7 +128,6 @@
#define AM65_CPSW_PN_TS_CTL_LTYPE2_TS_319 BIT(21)
#define AM65_CPSW_PN_TS_CTL_LTYPE2_TS_320 BIT(22)
#define AM65_CPSW_PN_TS_CTL_LTYPE2_TS_TTL_NONZERO BIT(23)
#define AM65_CPSW_PN_TS_CTL_LTYPE2_TS_UNI_EN BIT(24)
/* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */
#define AM65_CPSW_TS_EVENT_MSG_TYPE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3))
@ -1858,8 +1857,7 @@ static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev,
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_132 |
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_319 |
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_320 |
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_TTL_NONZERO |
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_UNI_EN;
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_TTL_NONZERO;
ts_ctrl = AM65_CPSW_TS_EVENT_MSG_TYPE_BITS <<
AM65_CPSW_PN_TS_CTL_MSG_TYPE_EN_SHIFT;

View File

@ -176,9 +176,6 @@ struct am65_cpts {
struct mutex ptp_clk_lock; /* PHC access sync */
u64 timestamp;
u32 genf_enable;
bool genf_neg_adj;
u32 genf_ppm_hi;
u32 genf_ppm_low;
u32 hw_ts_enable;
u32 estf_enable;
struct sk_buff_head txq;
@ -439,11 +436,9 @@ static int am65_cpts_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info);
u32 estf_ctrl_val = 0, estf_ppm_hi = 0, estf_ppm_low = 0;
u32 genf_ctrl_val[AM65_CPTS_GENF_MAX_NUM];
u32 genf_ppm_hi, genf_ppm_low;
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
int pps_index = cpts->pps_genf_idx;
u64 adj_period, genf_adj_period;
u64 adj_period, pps_adj_period;
u32 ctrl_val, ppm_hi, ppm_low;
unsigned long flags;
int neg_adj = 0, i;
@ -475,33 +470,20 @@ static int am65_cpts_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
ppm_hi = upper_32_bits(adj_period) & 0x3FF;
ppm_low = lower_32_bits(adj_period);
/* GenF PPM will do correction using cpts refclk tick which is
* (cpts->ts_add_val + 1) ns, so GenF length PPM adj period
* need to be corrected.
*/
genf_adj_period = adj_period * (cpts->ts_add_val + 1);
genf_ppm_hi = upper_32_bits(genf_adj_period) & 0x3FF;
genf_ppm_low = lower_32_bits(genf_adj_period);
cpts->genf_neg_adj = neg_adj;
cpts->genf_ppm_hi = genf_ppm_hi;
cpts->genf_ppm_low = genf_ppm_low;
for (i = 0; i < AM65_CPTS_GENF_MAX_NUM; i++) {
if (cpts->genf_enable & BIT(i)) {
genf_ctrl_val[i] = am65_cpts_read32(cpts,
genf[i].control);
if (neg_adj)
genf_ctrl_val[i] &= ~BIT(1);
else
genf_ctrl_val[i] |= BIT(1);
}
}
if (cpts->pps_enabled) {
/* am65_cpts_perout_enable_hw() sets pps_index in genf_enable */
estf_ctrl_val = genf_ctrl_val[pps_index];
estf_ppm_hi = genf_ppm_hi;
estf_ppm_low = genf_ppm_low;
estf_ctrl_val = am65_cpts_read32(cpts, genf[pps_index].control);
if (neg_adj)
estf_ctrl_val &= ~BIT(1);
else
estf_ctrl_val |= BIT(1);
/* GenF PPM will do correction using cpts refclk tick which is
* (cpts->ts_add_val + 1) ns, so GenF length PPM adj period
* need to be corrected.
*/
pps_adj_period = adj_period * (cpts->ts_add_val + 1);
estf_ppm_hi = upper_32_bits(pps_adj_period) & 0x3FF;
estf_ppm_low = lower_32_bits(pps_adj_period);
}
spin_lock_irqsave(&cpts->lock, flags);
@ -518,13 +500,10 @@ static int am65_cpts_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
am65_cpts_write32(cpts, ppm_hi, ts_ppm_hi);
am65_cpts_write32(cpts, ppm_low, ts_ppm_low);
for (i = 0; i < AM65_CPTS_GENF_MAX_NUM; i++) {
if (cpts->genf_enable & BIT(i)) {
am65_cpts_write32(cpts, genf_ctrl_val[i],
genf[i].control);
am65_cpts_write32(cpts, genf_ppm_hi, genf[i].ppm_hi);
am65_cpts_write32(cpts, genf_ppm_low, genf[i].ppm_low);
}
if (cpts->pps_enabled) {
am65_cpts_write32(cpts, estf_ctrl_val, genf[pps_index].control);
am65_cpts_write32(cpts, estf_ppm_hi, genf[pps_index].ppm_hi);
am65_cpts_write32(cpts, estf_ppm_low, genf[pps_index].ppm_low);
}
for (i = 0; i < AM65_CPTS_ESTF_MAX_NUM; i++) {
@ -534,6 +513,7 @@ static int am65_cpts_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
am65_cpts_write32(cpts, estf_ppm_low, estf[i].ppm_low);
}
}
/* All GenF/EstF can be updated here the same way */
spin_unlock_irqrestore(&cpts->lock, flags);
mutex_unlock(&cpts->ptp_clk_lock);
@ -699,12 +679,9 @@ static void am65_cpts_perout_enable_hw(struct am65_cpts *cpts,
val = lower_32_bits(cycles);
am65_cpts_write32(cpts, val, genf[req->index].length);
am65_cpts_write32(cpts, cpts->genf_neg_adj ? 0 : BIT(1),
genf[req->index].control);
am65_cpts_write32(cpts, cpts->genf_ppm_hi,
genf[req->index].ppm_hi);
am65_cpts_write32(cpts, cpts->genf_ppm_low,
genf[req->index].ppm_low);
am65_cpts_write32(cpts, 0, genf[req->index].control);
am65_cpts_write32(cpts, 0, genf[req->index].ppm_hi);
am65_cpts_write32(cpts, 0, genf[req->index].ppm_low);
cpts->genf_enable |= BIT(req->index);
} else {

View File

@ -260,8 +260,10 @@ int ipa_interrupt_config(struct ipa *ipa)
interrupt->enabled = 0;
interrupt->suspend_enabled = bitmap_zalloc(ipa->endpoint_count,
GFP_KERNEL);
if (!interrupt->suspend_enabled)
return -ENOMEM;
if (!interrupt->suspend_enabled) {
ret = -ENOMEM;
goto err_kfree;
}
/* Disable IPA interrupt types */
reg = ipa_reg(ipa, IPA_IRQ_EN);
@ -287,6 +289,8 @@ int ipa_interrupt_config(struct ipa *ipa)
goto err_disable_wakeup;
}
ipa->interrupt = interrupt;
return 0;
err_disable_wakeup:
@ -295,6 +299,8 @@ int ipa_interrupt_config(struct ipa *ipa)
free_irq(interrupt->irq, interrupt);
err_free_bitmap:
bitmap_free(interrupt->suspend_enabled);
err_kfree:
kfree(interrupt);
return ret;
}
@ -305,6 +311,8 @@ void ipa_interrupt_deconfig(struct ipa *ipa)
struct ipa_interrupt *interrupt = ipa->interrupt;
struct device *dev = ipa->dev;
ipa->interrupt = NULL;
dev_pm_clear_wake_irq(dev);
(void)device_init_wakeup(dev, false);
free_irq(interrupt->irq, interrupt);

View File

@ -643,14 +643,6 @@ static int macvlan_open(struct net_device *dev)
if (err < 0)
goto out;
}
if (dev->flags & IFF_ALLMULTI) {
err = dev_set_allmulti(lowerdev, 1);
if (err < 0) {
if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
dev_set_promiscuity(lowerdev, -1);
goto out;
}
}
goto hash_add;
}
@ -721,8 +713,6 @@ static int macvlan_stop(struct net_device *dev)
dev_mc_unsync(lowerdev, dev);
if (macvlan_passthru(vlan->port)) {
if (dev->flags & IFF_ALLMULTI)
dev_set_allmulti(lowerdev, -1);
if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
dev_set_promiscuity(lowerdev, -1);
goto hash_del;

View File

@ -111,7 +111,8 @@ static int mctp_i3c_read(struct mctp_i3c_device *mi)
mi->mrl + sizeof(struct mctp_i3c_internal_hdr));
if (!skb) {
stats->rx_dropped++;
return -ENOMEM;
rc = -ENOMEM;
goto err;
}
skb->protocol = htons(ETH_P_MCTP);

View File

@ -1826,13 +1826,9 @@ static void phy_detach_internal(struct phy_device *phydev, bool notify_bus)
struct hwtstamp_provider *hwprov;
/* hwprov may technically be protected by ops lock but
* not for devices with a phydev, see phy_link_topo_add_phy().
* Drivers may detach without RTNL while dev is unregistered,
* but then nothing else can reach hwprov.
* not for devices with a phydev, see phy_link_topo_add_phy()
*/
hwprov = rcu_dereference_protected(dev->hwprov,
lockdep_rtnl_is_held() ||
dev->reg_state != NETREG_REGISTERED);
hwprov = rtnl_dereference(dev->hwprov);
/* Disable timestamp if it is the one selected */
if (hwprov && hwprov->phydev == phydev) {
rcu_assign_pointer(dev->hwprov, NULL);

View File

@ -1377,10 +1377,9 @@ static int veth_set_channels(struct net_device *dev,
* to identify the range we have to disable
*/
veth_disable_range_safe(dev, new_rx_count, old_rx_count);
if (peer && (peer->flags & IFF_UP)) {
netif_carrier_on(dev);
netif_carrier_on(dev);
if (peer)
netif_carrier_on(peer);
}
}
/* update XDP supported features */

View File

@ -1005,6 +1005,12 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
return -EOPNOTSUPP;
}
if (rcu_access_pointer(f->nh) &&
!(state & (NUD_PERMANENT | NUD_NOARP))) {
NL_SET_ERR_MSG(extack, "Cannot make a nexthop fdb dynamic");
return -EOPNOTSUPP;
}
/* Do not allow an externally learned entry to take over an entry added
* by the user.
*/
@ -1268,6 +1274,11 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
if (err)
return err;
if (nhid && !(ndm->ndm_state & (NUD_PERMANENT | NUD_NOARP))) {
NL_SET_ERR_MSG(extack, "A nexthop fdb cannot be dynamic");
return -EINVAL;
}
cfg = rtnl_dereference(vxlan->cfg);
if (cfg->remote_ip.sa.sa_family != ip.sa.sa_family)
return -EAFNOSUPPORT;
@ -2936,9 +2947,6 @@ static void vxlan_cleanup(struct timer_list *t)
if (f->flags & NTF_EXT_LEARNED)
continue;
if (rcu_access_pointer(f->nh))
continue;
timeout = READ_ONCE(f->updated) + cfg->age_interval * HZ;
if (time_before_eq(timeout, jiffies)) {
spin_lock(&vxlan->hash_lock);

Some files were not shown because too many files have changed in this diff Show More