mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 05:55:44 +02:00
Merge a1d21081a6 ("Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net") into android-mainline
Steps on the way to 5.9-rc1 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I927040e73701d3ed235f871edd336beaa575ad96
This commit is contained in:
commit
682b15d471
9
.mailmap
9
.mailmap
|
|
@ -2,11 +2,16 @@
|
|||
# This list is used by git-shortlog to fix a few botched name translations
|
||||
# in the git archive, either because the author's full name was messed up
|
||||
# and/or not always written the same way, making contributions from the
|
||||
# same person appearing not to be so or badly displayed.
|
||||
# same person appearing not to be so or badly displayed. Also allows for
|
||||
# old email addresses to map to new email addresses.
|
||||
#
|
||||
# For format details, see "MAPPING AUTHORS" in "man git-shortlog".
|
||||
#
|
||||
# Please keep this list dictionary sorted.
|
||||
#
|
||||
# This comment is parsed by git-shortlog:
|
||||
# repo-abbrev: /pub/scm/linux/kernel/git/
|
||||
#
|
||||
|
||||
Aaron Durbin <adurbin@google.com>
|
||||
Adam Oldham <oldhamca@gmail.com>
|
||||
Adam Radford <aradford@gmail.com>
|
||||
|
|
|
|||
|
|
@ -724,7 +724,7 @@
|
|||
memory region [offset, offset + size] for that kernel
|
||||
image. If '@offset' is omitted, then a suitable offset
|
||||
is selected automatically.
|
||||
[KNL, x86_64] select a region under 4G first, and
|
||||
[KNL, X86-64] Select a region under 4G first, and
|
||||
fall back to reserve region above 4G when '@offset'
|
||||
hasn't been specified.
|
||||
See Documentation/admin-guide/kdump/kdump.rst for further details.
|
||||
|
|
@ -737,14 +737,14 @@
|
|||
Documentation/admin-guide/kdump/kdump.rst for an example.
|
||||
|
||||
crashkernel=size[KMG],high
|
||||
[KNL, x86_64] range could be above 4G. Allow kernel
|
||||
[KNL, X86-64] range could be above 4G. Allow kernel
|
||||
to allocate physical memory region from top, so could
|
||||
be above 4G if system have more than 4G ram installed.
|
||||
Otherwise memory region will be allocated below 4G, if
|
||||
available.
|
||||
It will be ignored if crashkernel=X is specified.
|
||||
crashkernel=size[KMG],low
|
||||
[KNL, x86_64] range under 4G. When crashkernel=X,high
|
||||
[KNL, X86-64] range under 4G. When crashkernel=X,high
|
||||
is passed, kernel could allocate physical memory region
|
||||
above 4G, that cause second kernel crash on system
|
||||
that require some amount of low memory, e.g. swiotlb
|
||||
|
|
@ -1427,7 +1427,7 @@
|
|||
|
||||
gamma= [HW,DRM]
|
||||
|
||||
gart_fix_e820= [X86_64] disable the fix e820 for K8 GART
|
||||
gart_fix_e820= [X86-64] disable the fix e820 for K8 GART
|
||||
Format: off | on
|
||||
default: on
|
||||
|
||||
|
|
@ -1814,7 +1814,7 @@
|
|||
Format: 0 | 1
|
||||
Default set by CONFIG_INIT_ON_FREE_DEFAULT_ON.
|
||||
|
||||
init_pkru= [x86] Specify the default memory protection keys rights
|
||||
init_pkru= [X86] Specify the default memory protection keys rights
|
||||
register contents for all processes. 0x55555554 by
|
||||
default (disallow access to all but pkey 0). Can
|
||||
override in debugfs after boot.
|
||||
|
|
@ -1822,7 +1822,7 @@
|
|||
inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
|
||||
Format: <irq>
|
||||
|
||||
int_pln_enable [x86] Enable power limit notification interrupt
|
||||
int_pln_enable [X86] Enable power limit notification interrupt
|
||||
|
||||
integrity_audit=[IMA]
|
||||
Format: { "0" | "1" }
|
||||
|
|
@ -1840,7 +1840,7 @@
|
|||
bypassed by not enabling DMAR with this option. In
|
||||
this case, gfx device will use physical address for
|
||||
DMA.
|
||||
forcedac [x86_64]
|
||||
forcedac [X86-64]
|
||||
With this option iommu will not optimize to look
|
||||
for io virtual address below 32-bit forcing dual
|
||||
address cycle on pci bus for cards supporting greater
|
||||
|
|
@ -1925,7 +1925,7 @@
|
|||
strict regions from userspace.
|
||||
relaxed
|
||||
|
||||
iommu= [x86]
|
||||
iommu= [X86]
|
||||
off
|
||||
force
|
||||
noforce
|
||||
|
|
@ -1935,8 +1935,8 @@
|
|||
merge
|
||||
nomerge
|
||||
soft
|
||||
pt [x86]
|
||||
nopt [x86]
|
||||
pt [X86]
|
||||
nopt [X86]
|
||||
nobypass [PPC/POWERNV]
|
||||
Disable IOMMU bypass, using IOMMU for PCI devices.
|
||||
|
||||
|
|
@ -2079,21 +2079,21 @@
|
|||
|
||||
iucv= [HW,NET]
|
||||
|
||||
ivrs_ioapic [HW,X86_64]
|
||||
ivrs_ioapic [HW,X86-64]
|
||||
Provide an override to the IOAPIC-ID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table. For
|
||||
example, to map IOAPIC-ID decimal 10 to
|
||||
PCI device 00:14.0 write the parameter as:
|
||||
ivrs_ioapic[10]=00:14.0
|
||||
|
||||
ivrs_hpet [HW,X86_64]
|
||||
ivrs_hpet [HW,X86-64]
|
||||
Provide an override to the HPET-ID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table. For
|
||||
example, to map HPET-ID decimal 0 to
|
||||
PCI device 00:14.0 write the parameter as:
|
||||
ivrs_hpet[0]=00:14.0
|
||||
|
||||
ivrs_acpihid [HW,X86_64]
|
||||
ivrs_acpihid [HW,X86-64]
|
||||
Provide an override to the ACPI-HID:UID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table. For
|
||||
example, to map UART-HID:UID AMD0020:0 to
|
||||
|
|
@ -2370,7 +2370,7 @@
|
|||
lapic [X86-32,APIC] Enable the local APIC even if BIOS
|
||||
disabled it.
|
||||
|
||||
lapic= [x86,APIC] "notscdeadline" Do not use TSC deadline
|
||||
lapic= [X86,APIC] "notscdeadline" Do not use TSC deadline
|
||||
value for LAPIC timer one-shot implementation. Default
|
||||
back to the programmable timer unit in the LAPIC.
|
||||
|
||||
|
|
@ -3188,12 +3188,12 @@
|
|||
register save and restore. The kernel will only save
|
||||
legacy floating-point registers on task switch.
|
||||
|
||||
nohugeiomap [KNL,x86,PPC] Disable kernel huge I/O mappings.
|
||||
nohugeiomap [KNL,X86,PPC] Disable kernel huge I/O mappings.
|
||||
|
||||
nosmt [KNL,S390] Disable symmetric multithreading (SMT).
|
||||
Equivalent to smt=1.
|
||||
|
||||
[KNL,x86] Disable symmetric multithreading (SMT).
|
||||
[KNL,X86] Disable symmetric multithreading (SMT).
|
||||
nosmt=force: Force disable SMT, cannot be undone
|
||||
via the sysfs control file.
|
||||
|
||||
|
|
@ -3955,7 +3955,7 @@
|
|||
pt. [PARIDE]
|
||||
See Documentation/admin-guide/blockdev/paride.rst.
|
||||
|
||||
pti= [X86_64] Control Page Table Isolation of user and
|
||||
pti= [X86-64] Control Page Table Isolation of user and
|
||||
kernel address spaces. Disabling this feature
|
||||
removes hardening, but improves performance of
|
||||
system calls and interrupts.
|
||||
|
|
@ -3967,7 +3967,7 @@
|
|||
|
||||
Not specifying this option is equivalent to pti=auto.
|
||||
|
||||
nopti [X86_64]
|
||||
nopti [X86-64]
|
||||
Equivalent to pti=off
|
||||
|
||||
pty.legacy_count=
|
||||
|
|
|
|||
|
|
@ -246,17 +246,6 @@ program is loaded the kernel will print warning message, so
|
|||
this helper is only useful for experiments and prototypes.
|
||||
Tracing BPF programs are root only.
|
||||
|
||||
Q: bpf_trace_printk() helper warning
|
||||
------------------------------------
|
||||
Q: When bpf_trace_printk() helper is used the kernel prints nasty
|
||||
warning message. Why is that?
|
||||
|
||||
A: This is done to nudge program authors into better interfaces when
|
||||
programs need to pass data to user space. Like bpf_perf_event_output()
|
||||
can be used to efficiently stream data via perf ring buffer.
|
||||
BPF maps can be used for asynchronous data sharing between kernel
|
||||
and user space. bpf_trace_printk() should only be used for debugging.
|
||||
|
||||
Q: New functionality via kernel modules?
|
||||
----------------------------------------
|
||||
Q: Can BPF functionality such as new program or map types, new
|
||||
|
|
|
|||
|
|
@ -557,7 +557,7 @@ phase. Currently, the capabilities are any of::
|
|||
CDC_DRIVE_STATUS /* driver implements drive status */
|
||||
|
||||
The capability flag is declared *const*, to prevent drivers from
|
||||
accidentally tampering with the contents. The capability fags actually
|
||||
accidentally tampering with the contents. The capability flags actually
|
||||
inform `cdrom.c` of what the driver can do. If the drive found
|
||||
by the driver does not have the capability, is can be masked out by
|
||||
the *cdrom_device_info* variable *mask*. For instance, the SCSI CD-ROM
|
||||
|
|
@ -736,7 +736,7 @@ Description of routines in `cdrom.c`
|
|||
|
||||
Only a few routines in `cdrom.c` are exported to the drivers. In this
|
||||
new section we will discuss these, as well as the functions that `take
|
||||
over' the CD-ROM interface to the kernel. The header file belonging
|
||||
over` the CD-ROM interface to the kernel. The header file belonging
|
||||
to `cdrom.c` is called `cdrom.h`. Formerly, some of the contents of this
|
||||
file were placed in the file `ucdrom.h`, but this file has now been
|
||||
merged back into `cdrom.h`.
|
||||
|
|
|
|||
|
|
@ -20,48 +20,48 @@ only ID allocation, and as a result is much more memory-efficient.
|
|||
IDR usage
|
||||
=========
|
||||
|
||||
Start by initialising an IDR, either with :c:func:`DEFINE_IDR`
|
||||
for statically allocated IDRs or :c:func:`idr_init` for dynamically
|
||||
Start by initialising an IDR, either with DEFINE_IDR()
|
||||
for statically allocated IDRs or idr_init() for dynamically
|
||||
allocated IDRs.
|
||||
|
||||
You can call :c:func:`idr_alloc` to allocate an unused ID. Look up
|
||||
the pointer you associated with the ID by calling :c:func:`idr_find`
|
||||
and free the ID by calling :c:func:`idr_remove`.
|
||||
You can call idr_alloc() to allocate an unused ID. Look up
|
||||
the pointer you associated with the ID by calling idr_find()
|
||||
and free the ID by calling idr_remove().
|
||||
|
||||
If you need to change the pointer associated with an ID, you can call
|
||||
:c:func:`idr_replace`. One common reason to do this is to reserve an
|
||||
idr_replace(). One common reason to do this is to reserve an
|
||||
ID by passing a ``NULL`` pointer to the allocation function; initialise the
|
||||
object with the reserved ID and finally insert the initialised object
|
||||
into the IDR.
|
||||
|
||||
Some users need to allocate IDs larger than ``INT_MAX``. So far all of
|
||||
these users have been content with a ``UINT_MAX`` limit, and they use
|
||||
:c:func:`idr_alloc_u32`. If you need IDs that will not fit in a u32,
|
||||
idr_alloc_u32(). If you need IDs that will not fit in a u32,
|
||||
we will work with you to address your needs.
|
||||
|
||||
If you need to allocate IDs sequentially, you can use
|
||||
:c:func:`idr_alloc_cyclic`. The IDR becomes less efficient when dealing
|
||||
idr_alloc_cyclic(). The IDR becomes less efficient when dealing
|
||||
with larger IDs, so using this function comes at a slight cost.
|
||||
|
||||
To perform an action on all pointers used by the IDR, you can
|
||||
either use the callback-based :c:func:`idr_for_each` or the
|
||||
iterator-style :c:func:`idr_for_each_entry`. You may need to use
|
||||
:c:func:`idr_for_each_entry_continue` to continue an iteration. You can
|
||||
also use :c:func:`idr_get_next` if the iterator doesn't fit your needs.
|
||||
either use the callback-based idr_for_each() or the
|
||||
iterator-style idr_for_each_entry(). You may need to use
|
||||
idr_for_each_entry_continue() to continue an iteration. You can
|
||||
also use idr_get_next() if the iterator doesn't fit your needs.
|
||||
|
||||
When you have finished using an IDR, you can call :c:func:`idr_destroy`
|
||||
When you have finished using an IDR, you can call idr_destroy()
|
||||
to release the memory used by the IDR. This will not free the objects
|
||||
pointed to from the IDR; if you want to do that, use one of the iterators
|
||||
to do it.
|
||||
|
||||
You can use :c:func:`idr_is_empty` to find out whether there are any
|
||||
You can use idr_is_empty() to find out whether there are any
|
||||
IDs currently allocated.
|
||||
|
||||
If you need to take a lock while allocating a new ID from the IDR,
|
||||
you may need to pass a restrictive set of GFP flags, which can lead
|
||||
to the IDR being unable to allocate memory. To work around this,
|
||||
you can call :c:func:`idr_preload` before taking the lock, and then
|
||||
:c:func:`idr_preload_end` after the allocation.
|
||||
you can call idr_preload() before taking the lock, and then
|
||||
idr_preload_end() after the allocation.
|
||||
|
||||
.. kernel-doc:: include/linux/idr.h
|
||||
:doc: idr sync
|
||||
|
|
|
|||
|
|
@ -175,13 +175,20 @@ For example, to check drivers/net/wireless/ one may write::
|
|||
make coccicheck M=drivers/net/wireless/
|
||||
|
||||
To apply Coccinelle on a file basis, instead of a directory basis, the
|
||||
following command may be used::
|
||||
C variable is used by the makefile to select which files to work with.
|
||||
This variable can be used to run scripts for the entire kernel, a
|
||||
specific directory, or for a single file.
|
||||
|
||||
make C=1 CHECK="scripts/coccicheck"
|
||||
For example, to check drivers/bluetooth/bfusb.c, the value 1 is
|
||||
passed to the C variable to check files that make considers
|
||||
need to be compiled.::
|
||||
|
||||
To check only newly edited code, use the value 2 for the C flag, i.e.::
|
||||
make C=1 CHECK=scripts/coccicheck drivers/bluetooth/bfusb.o
|
||||
|
||||
make C=2 CHECK="scripts/coccicheck"
|
||||
The value 2 is passed to the C variable to check files regardless of
|
||||
whether they need to be compiled or not.::
|
||||
|
||||
make C=2 CHECK=scripts/coccicheck drivers/bluetooth/bfusb.o
|
||||
|
||||
In these modes, which work on a file basis, there is no information
|
||||
about semantic patches displayed, and no commit message proposed.
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ driver as a loadable kernel module kgdbwait will not do anything.
|
|||
Kernel parameter: ``kgdbcon``
|
||||
-----------------------------
|
||||
|
||||
The ``kgdbcon`` feature allows you to see :c:func:`printk` messages inside gdb
|
||||
The ``kgdbcon`` feature allows you to see printk() messages inside gdb
|
||||
while gdb is connected to the kernel. Kdb does not make use of the kgdbcon
|
||||
feature.
|
||||
|
||||
|
|
@ -432,7 +432,7 @@ This is a quick example of how to use kdb.
|
|||
``ps`` Displays only the active processes
|
||||
``ps A`` Shows all the processes
|
||||
``summary`` Shows kernel version info and memory usage
|
||||
``bt`` Get a backtrace of the current process using :c:func:`dump_stack`
|
||||
``bt`` Get a backtrace of the current process using dump_stack()
|
||||
``dmesg`` View the kernel syslog buffer
|
||||
``go`` Continue the system
|
||||
=========== =================================================================
|
||||
|
|
@ -724,7 +724,7 @@ The kernel debugger is organized into a number of components:
|
|||
The arch-specific portion implements:
|
||||
|
||||
- contains an arch-specific trap catcher which invokes
|
||||
:c:func:`kgdb_handle_exception` to start kgdb about doing its work
|
||||
kgdb_handle_exception() to start kgdb about doing its work
|
||||
|
||||
- translation to and from gdb specific packet format to :c:type:`pt_regs`
|
||||
|
||||
|
|
@ -769,7 +769,7 @@ The kernel debugger is organized into a number of components:
|
|||
config. Later run ``modprobe kdb_hello`` and the next time you
|
||||
enter the kdb shell, you can run the ``hello`` command.
|
||||
|
||||
- The implementation for :c:func:`kdb_printf` which emits messages directly
|
||||
- The implementation for kdb_printf() which emits messages directly
|
||||
to I/O drivers, bypassing the kernel log.
|
||||
|
||||
- SW / HW breakpoint management for the kdb shell
|
||||
|
|
@ -875,7 +875,7 @@ kernel when ``CONFIG_KDB_KEYBOARD=y`` is set in the kernel configuration.
|
|||
The core polled keyboard driver for PS/2 type keyboards is in
|
||||
``drivers/char/kdb_keyboard.c``. This driver is hooked into the debug core
|
||||
when kgdboc populates the callback in the array called
|
||||
:c:type:`kdb_poll_funcs[]`. The :c:func:`kdb_get_kbd_char` is the top-level
|
||||
:c:type:`kdb_poll_funcs[]`. The kdb_get_kbd_char() is the top-level
|
||||
function which polls hardware for single character input.
|
||||
|
||||
kgdboc and kms
|
||||
|
|
@ -887,10 +887,10 @@ that you have a video driver which has a frame buffer console and atomic
|
|||
kernel mode setting support.
|
||||
|
||||
Every time the kernel debugger is entered it calls
|
||||
:c:func:`kgdboc_pre_exp_handler` which in turn calls :c:func:`con_debug_enter`
|
||||
kgdboc_pre_exp_handler() which in turn calls con_debug_enter()
|
||||
in the virtual console layer. On resuming kernel execution, the kernel
|
||||
debugger calls :c:func:`kgdboc_post_exp_handler` which in turn calls
|
||||
:c:func:`con_debug_leave`.
|
||||
debugger calls kgdboc_post_exp_handler() which in turn calls
|
||||
con_debug_leave().
|
||||
|
||||
Any video driver that wants to be compatible with the kernel debugger
|
||||
and the atomic kms callbacks must implement the ``mode_set_base_atomic``,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ Required properties:
|
|||
"mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek MT7629
|
||||
"mediatek,mt8173-i2c": for MediaTek MT8173
|
||||
"mediatek,mt8183-i2c": for MediaTek MT8183
|
||||
"mediatek,mt8192-i2c": for MediaTek MT8192
|
||||
"mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516
|
||||
- reg: physical base address of the controller and dma base, length of memory
|
||||
mapped region.
|
||||
|
|
|
|||
|
|
@ -72,6 +72,16 @@ wants to support one of the below features, it should adapt these bindings.
|
|||
this information to adapt power management to keep the arbitration awake
|
||||
all the time, for example. Can not be combined with 'single-master'.
|
||||
|
||||
- pinctrl
|
||||
add extra pinctrl to configure SCL/SDA pins to GPIO function for bus
|
||||
recovery, call it "gpio" or "recovery" (deprecated) state
|
||||
|
||||
- scl-gpios
|
||||
specify the gpio related to SCL pin. Used for GPIO bus recovery.
|
||||
|
||||
- sda-gpios
|
||||
specify the gpio related to SDA pin. Optional for GPIO bus recovery.
|
||||
|
||||
- single-master
|
||||
states that there is no other master active on this bus. The OS can use
|
||||
this information to detect a stalled bus more reliably, for example.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ properties:
|
|||
- items:
|
||||
- const: allwinner,sun50i-a64-i2c
|
||||
- const: allwinner,sun6i-a31-i2c
|
||||
- items:
|
||||
- const: allwinner,sun50i-a100-i2c
|
||||
- const: allwinner,sun6i-a31-i2c
|
||||
- items:
|
||||
- const: allwinner,sun50i-h6-i2c
|
||||
- const: allwinner,sun6i-a31-i2c
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Required properties:
|
|||
"renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC.
|
||||
"renesas,i2c-r8a774b1" if the device is a part of a R8A774B1 SoC.
|
||||
"renesas,i2c-r8a774c0" if the device is a part of a R8A774C0 SoC.
|
||||
"renesas,i2c-r8a774e1" if the device is a part of a R8A774E1 SoC.
|
||||
"renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC.
|
||||
"renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC.
|
||||
"renesas,i2c-r8a7790" if the device is a part of a R8A7790 SoC.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ Required properties:
|
|||
- "renesas,iic-r8a774a1" (RZ/G2M)
|
||||
- "renesas,iic-r8a774b1" (RZ/G2N)
|
||||
- "renesas,iic-r8a774c0" (RZ/G2E)
|
||||
- "renesas,iic-r8a774e1" (RZ/G2H)
|
||||
- "renesas,iic-r8a7790" (R-Car H2)
|
||||
- "renesas,iic-r8a7791" (R-Car M2-W)
|
||||
- "renesas,iic-r8a7792" (R-Car V2H)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | ok |
|
||||
| sh: | ok |
|
||||
| sparc: | ok |
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | TODO |
|
||||
| sh: | ok |
|
||||
| sparc: | TODO |
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
| openrisc: | ok |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | ok |
|
||||
| sh: | ok |
|
||||
| sparc: | ok |
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | TODO |
|
||||
| sh: | TODO |
|
||||
| sparc: | ok |
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@ Details
|
|||
The journalling layer is easy to use. You need to first of all create a
|
||||
journal_t data structure. There are two calls to do this dependent on
|
||||
how you decide to allocate the physical media on which the journal
|
||||
resides. The :c:func:`jbd2_journal_init_inode` call is for journals stored in
|
||||
filesystem inodes, or the :c:func:`jbd2_journal_init_dev` call can be used
|
||||
resides. The jbd2_journal_init_inode() call is for journals stored in
|
||||
filesystem inodes, or the jbd2_journal_init_dev() call can be used
|
||||
for journal stored on a raw device (in a continuous range of blocks). A
|
||||
journal_t is a typedef for a struct pointer, so when you are finally
|
||||
finished make sure you call :c:func:`jbd2_journal_destroy` on it to free up
|
||||
finished make sure you call jbd2_journal_destroy() on it to free up
|
||||
any used kernel memory.
|
||||
|
||||
Once you have got your journal_t object you need to 'mount' or load the
|
||||
journal file. The journalling layer expects the space for the journal
|
||||
was already allocated and initialized properly by the userspace tools.
|
||||
When loading the journal you must call :c:func:`jbd2_journal_load` to process
|
||||
When loading the journal you must call jbd2_journal_load() to process
|
||||
journal contents. If the client file system detects the journal contents
|
||||
does not need to be processed (or even need not have valid contents), it
|
||||
may call :c:func:`jbd2_journal_wipe` to clear the journal contents before
|
||||
calling :c:func:`jbd2_journal_load`.
|
||||
may call jbd2_journal_wipe() to clear the journal contents before
|
||||
calling jbd2_journal_load().
|
||||
|
||||
Note that jbd2_journal_wipe(..,0) calls
|
||||
:c:func:`jbd2_journal_skip_recovery` for you if it detects any outstanding
|
||||
transactions in the journal and similarly :c:func:`jbd2_journal_load` will
|
||||
call :c:func:`jbd2_journal_recover` if necessary. I would advise reading
|
||||
:c:func:`ext4_load_journal` in fs/ext4/super.c for examples on this stage.
|
||||
jbd2_journal_skip_recovery() for you if it detects any outstanding
|
||||
transactions in the journal and similarly jbd2_journal_load() will
|
||||
call jbd2_journal_recover() if necessary. I would advise reading
|
||||
ext4_load_journal() in fs/ext4/super.c for examples on this stage.
|
||||
|
||||
Now you can go ahead and start modifying the underlying filesystem.
|
||||
Almost.
|
||||
|
|
@ -39,57 +39,57 @@ You still need to actually journal your filesystem changes, this is done
|
|||
by wrapping them into transactions. Additionally you also need to wrap
|
||||
the modification of each of the buffers with calls to the journal layer,
|
||||
so it knows what the modifications you are actually making are. To do
|
||||
this use :c:func:`jbd2_journal_start` which returns a transaction handle.
|
||||
this use jbd2_journal_start() which returns a transaction handle.
|
||||
|
||||
:c:func:`jbd2_journal_start` and its counterpart :c:func:`jbd2_journal_stop`,
|
||||
jbd2_journal_start() and its counterpart jbd2_journal_stop(),
|
||||
which indicates the end of a transaction are nestable calls, so you can
|
||||
reenter a transaction if necessary, but remember you must call
|
||||
:c:func:`jbd2_journal_stop` the same number of times as
|
||||
:c:func:`jbd2_journal_start` before the transaction is completed (or more
|
||||
jbd2_journal_stop() the same number of times as
|
||||
jbd2_journal_start() before the transaction is completed (or more
|
||||
accurately leaves the update phase). Ext4/VFS makes use of this feature to
|
||||
simplify handling of inode dirtying, quota support, etc.
|
||||
|
||||
Inside each transaction you need to wrap the modifications to the
|
||||
individual buffers (blocks). Before you start to modify a buffer you
|
||||
need to call :c:func:`jbd2_journal_get_create_access()` /
|
||||
:c:func:`jbd2_journal_get_write_access()` /
|
||||
:c:func:`jbd2_journal_get_undo_access()` as appropriate, this allows the
|
||||
need to call jbd2_journal_get_create_access() /
|
||||
jbd2_journal_get_write_access() /
|
||||
jbd2_journal_get_undo_access() as appropriate, this allows the
|
||||
journalling layer to copy the unmodified
|
||||
data if it needs to. After all the buffer may be part of a previously
|
||||
uncommitted transaction. At this point you are at last ready to modify a
|
||||
buffer, and once you are have done so you need to call
|
||||
:c:func:`jbd2_journal_dirty_metadata`. Or if you've asked for access to a
|
||||
jbd2_journal_dirty_metadata(). Or if you've asked for access to a
|
||||
buffer you now know is now longer required to be pushed back on the
|
||||
device you can call :c:func:`jbd2_journal_forget` in much the same way as you
|
||||
might have used :c:func:`bforget` in the past.
|
||||
device you can call jbd2_journal_forget() in much the same way as you
|
||||
might have used bforget() in the past.
|
||||
|
||||
A :c:func:`jbd2_journal_flush` may be called at any time to commit and
|
||||
A jbd2_journal_flush() may be called at any time to commit and
|
||||
checkpoint all your transactions.
|
||||
|
||||
Then at umount time , in your :c:func:`put_super` you can then call
|
||||
:c:func:`jbd2_journal_destroy` to clean up your in-core journal object.
|
||||
Then at umount time , in your put_super() you can then call
|
||||
jbd2_journal_destroy() to clean up your in-core journal object.
|
||||
|
||||
Unfortunately there a couple of ways the journal layer can cause a
|
||||
deadlock. The first thing to note is that each task can only have a
|
||||
single outstanding transaction at any one time, remember nothing commits
|
||||
until the outermost :c:func:`jbd2_journal_stop`. This means you must complete
|
||||
until the outermost jbd2_journal_stop(). This means you must complete
|
||||
the transaction at the end of each file/inode/address etc. operation you
|
||||
perform, so that the journalling system isn't re-entered on another
|
||||
journal. Since transactions can't be nested/batched across differing
|
||||
journals, and another filesystem other than yours (say ext4) may be
|
||||
modified in a later syscall.
|
||||
|
||||
The second case to bear in mind is that :c:func:`jbd2_journal_start` can block
|
||||
The second case to bear in mind is that jbd2_journal_start() can block
|
||||
if there isn't enough space in the journal for your transaction (based
|
||||
on the passed nblocks param) - when it blocks it merely(!) needs to wait
|
||||
for transactions to complete and be committed from other tasks, so
|
||||
essentially we are waiting for :c:func:`jbd2_journal_stop`. So to avoid
|
||||
deadlocks you must treat :c:func:`jbd2_journal_start` /
|
||||
:c:func:`jbd2_journal_stop` as if they were semaphores and include them in
|
||||
essentially we are waiting for jbd2_journal_stop(). So to avoid
|
||||
deadlocks you must treat jbd2_journal_start() /
|
||||
jbd2_journal_stop() as if they were semaphores and include them in
|
||||
your semaphore ordering rules to prevent
|
||||
deadlocks. Note that :c:func:`jbd2_journal_extend` has similar blocking
|
||||
behaviour to :c:func:`jbd2_journal_start` so you can deadlock here just as
|
||||
easily as on :c:func:`jbd2_journal_start`.
|
||||
deadlocks. Note that jbd2_journal_extend() has similar blocking
|
||||
behaviour to jbd2_journal_start() so you can deadlock here just as
|
||||
easily as on jbd2_journal_start().
|
||||
|
||||
Try to reserve the right number of blocks the first time. ;-). This will
|
||||
be the maximum number of blocks you are going to touch in this
|
||||
|
|
@ -116,8 +116,8 @@ called after each transaction commit. You can also use
|
|||
that need processing when the transaction commits.
|
||||
|
||||
JBD2 also provides a way to block all transaction updates via
|
||||
:c:func:`jbd2_journal_lock_updates()` /
|
||||
:c:func:`jbd2_journal_unlock_updates()`. Ext4 uses this when it wants a
|
||||
jbd2_journal_lock_updates() /
|
||||
jbd2_journal_unlock_updates(). Ext4 uses this when it wants a
|
||||
window with a clean and stable fs for a moment. E.g.
|
||||
|
||||
::
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ Supported adapters:
|
|||
* Intel Elkhart Lake (PCH)
|
||||
* Intel Tiger Lake (PCH)
|
||||
* Intel Jasper Lake (SOC)
|
||||
* Intel Emmitsburg (PCH)
|
||||
|
||||
Datasheets: Publicly available at the Intel website
|
||||
|
||||
|
|
|
|||
|
|
@ -159,6 +159,8 @@ for details) through the following functions::
|
|||
__s32 i2c_smbus_read_word_data(int file, __u8 command);
|
||||
__s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
|
||||
__s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
|
||||
__s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
|
||||
__u8 *values);
|
||||
__s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
|
||||
__s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
|
||||
__u8 *values);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ Legacy documentation
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
upgrading-clients
|
||||
old-module-parameters
|
||||
|
||||
.. only:: subproject and html
|
||||
|
|
|
|||
|
|
@ -1,285 +0,0 @@
|
|||
=================================================
|
||||
Upgrading I2C Drivers to the new 2.6 Driver Model
|
||||
=================================================
|
||||
|
||||
Ben Dooks <ben-linux@fluff.org>
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This guide outlines how to alter existing Linux 2.6 client drivers from
|
||||
the old to the new binding methods.
|
||||
|
||||
|
||||
Example old-style driver
|
||||
------------------------
|
||||
|
||||
::
|
||||
|
||||
struct example_state {
|
||||
struct i2c_client client;
|
||||
....
|
||||
};
|
||||
|
||||
static struct i2c_driver example_driver;
|
||||
|
||||
static unsigned short ignore[] = { I2C_CLIENT_END };
|
||||
static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
|
||||
|
||||
I2C_CLIENT_INSMOD;
|
||||
|
||||
static int example_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &adap->dev; /* to use for dev_ reports */
|
||||
int ret;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
example->client.addr = addr;
|
||||
example->client.flags = 0;
|
||||
example->client.adapter = adap;
|
||||
|
||||
i2c_set_clientdata(&state->i2c_client, state);
|
||||
strscpy(client->i2c_client.name, "example", sizeof(client->i2c_client.name));
|
||||
|
||||
ret = i2c_attach_client(&state->i2c_client);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to attach client\n");
|
||||
kfree(state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev = &state->i2c_client.dev;
|
||||
|
||||
/* rest of the initialisation goes here. */
|
||||
|
||||
dev_info(dev, "example client created\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int example_detach(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
i2c_detach_client(client);
|
||||
kfree(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int example_attach_adapter(struct i2c_adapter *adap)
|
||||
{
|
||||
return i2c_probe(adap, &addr_data, example_attach);
|
||||
}
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
.pm = &example_pm_ops,
|
||||
},
|
||||
.attach_adapter = example_attach_adapter,
|
||||
.detach_client = example_detach,
|
||||
};
|
||||
|
||||
|
||||
Updating the client
|
||||
-------------------
|
||||
|
||||
The new style binding model will check against a list of supported
|
||||
devices and their associated address supplied by the code registering
|
||||
the busses. This means that the driver .attach_adapter and
|
||||
.detach_client methods can be removed, along with the addr_data,
|
||||
as follows::
|
||||
|
||||
- static struct i2c_driver example_driver;
|
||||
|
||||
- static unsigned short ignore[] = { I2C_CLIENT_END };
|
||||
- static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
|
||||
|
||||
- I2C_CLIENT_INSMOD;
|
||||
|
||||
- static int example_attach_adapter(struct i2c_adapter *adap)
|
||||
- {
|
||||
- return i2c_probe(adap, &addr_data, example_attach);
|
||||
- }
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
- .attach_adapter = example_attach_adapter,
|
||||
- .detach_client = example_detach,
|
||||
}
|
||||
|
||||
Add the probe and remove methods to the i2c_driver, as so::
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
+ .probe = example_probe,
|
||||
+ .remove = example_remove,
|
||||
}
|
||||
|
||||
Change the example_attach method to accept the new parameters
|
||||
which include the i2c_client that it will be working with::
|
||||
|
||||
- static int example_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
+ static int example_probe(struct i2c_client *client,
|
||||
+ const struct i2c_device_id *id)
|
||||
|
||||
Change the name of example_attach to example_probe to align it with the
|
||||
i2c_driver entry names. The rest of the probe routine will now need to be
|
||||
changed as the i2c_client has already been setup for use.
|
||||
|
||||
The necessary client fields have already been setup before
|
||||
the probe function is called, so the following client setup
|
||||
can be removed::
|
||||
|
||||
- example->client.addr = addr;
|
||||
- example->client.flags = 0;
|
||||
- example->client.adapter = adap;
|
||||
-
|
||||
- strscpy(client->i2c_client.name, "example", sizeof(client->i2c_client.name));
|
||||
|
||||
The i2c_set_clientdata is now::
|
||||
|
||||
- i2c_set_clientdata(&state->client, state);
|
||||
+ i2c_set_clientdata(client, state);
|
||||
|
||||
The call to i2c_attach_client is no longer needed, if the probe
|
||||
routine exits successfully, then the driver will be automatically
|
||||
attached by the core. Change the probe routine as so::
|
||||
|
||||
- ret = i2c_attach_client(&state->i2c_client);
|
||||
- if (ret < 0) {
|
||||
- dev_err(dev, "failed to attach client\n");
|
||||
- kfree(state);
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
|
||||
Remove the storage of 'struct i2c_client' from the 'struct example_state'
|
||||
as we are provided with the i2c_client in our example_probe. Instead we
|
||||
store a pointer to it for when it is needed.
|
||||
|
||||
::
|
||||
|
||||
struct example_state {
|
||||
- struct i2c_client client;
|
||||
+ struct i2c_client *client;
|
||||
|
||||
the new i2c client as so::
|
||||
|
||||
- struct device *dev = &adap->dev; /* to use for dev_ reports */
|
||||
+ struct device *dev = &i2c_client->dev; /* to use for dev_ reports */
|
||||
|
||||
And remove the change after our client is attached, as the driver no
|
||||
longer needs to register a new client structure with the core::
|
||||
|
||||
- dev = &state->i2c_client.dev;
|
||||
|
||||
In the probe routine, ensure that the new state has the client stored
|
||||
in it::
|
||||
|
||||
static int example_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &i2c_client->dev;
|
||||
int ret;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ state->client = i2c_client;
|
||||
|
||||
Update the detach method, by changing the name to _remove and
|
||||
to delete the i2c_detach_client call. It is possible that you
|
||||
can also remove the ret variable as it is not needed for any
|
||||
of the core functions.
|
||||
|
||||
::
|
||||
|
||||
- static int example_detach(struct i2c_client *client)
|
||||
+ static int example_remove(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
- i2c_detach_client(client);
|
||||
|
||||
And finally ensure that we have the correct ID table for the i2c-core
|
||||
and other utilities::
|
||||
|
||||
+ struct i2c_device_id example_idtable[] = {
|
||||
+ { "example", 0 },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(i2c, example_idtable);
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
},
|
||||
+ .id_table = example_ids,
|
||||
|
||||
|
||||
Our driver should now look like this::
|
||||
|
||||
struct example_state {
|
||||
struct i2c_client *client;
|
||||
....
|
||||
};
|
||||
|
||||
static int example_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &client->dev;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
state->client = client;
|
||||
i2c_set_clientdata(client, state);
|
||||
|
||||
/* rest of the initialisation goes here. */
|
||||
|
||||
dev_info(dev, "example client created\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int example_remove(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
kfree(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_device_id example_idtable[] = {
|
||||
{ "example", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, example_idtable);
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
.pm = &example_pm_ops,
|
||||
},
|
||||
.id_table = example_idtable,
|
||||
.probe = example_probe,
|
||||
.remove = example_remove,
|
||||
};
|
||||
|
|
@ -10,7 +10,7 @@ Introduction
|
|||
============
|
||||
|
||||
The kernel provides a variety of locking primitives which can be divided
|
||||
into two categories:
|
||||
into three categories:
|
||||
|
||||
- Sleeping locks
|
||||
- CPU local locks
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ than one development cycle past their initial release. So, for example, the
|
|||
5.2 kernel's history looked like this (all dates in 2019):
|
||||
|
||||
============== ===============================
|
||||
September 15 5.2 stable release
|
||||
July 7 5.2 stable release
|
||||
July 14 5.2.1
|
||||
July 21 5.2.2
|
||||
July 26 5.2.3
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ Bus and Subdevices
|
|||
|
||||
For each Intel TH device in the system a bus of its own is
|
||||
created and assigned an id number that reflects the order in which TH
|
||||
devices were emumerated. All TH subdevices (devices on intel_th bus)
|
||||
devices were enumerated. All TH subdevices (devices on intel_th bus)
|
||||
begin with this id: 0-gth, 0-msc0, 0-msc1, 0-pti, 0-sth, which is
|
||||
followed by device's name and an optional index.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
=======
|
||||
========
|
||||
CPU 负载
|
||||
=======
|
||||
========
|
||||
|
||||
Linux通过``/proc/stat``和``/proc/uptime``导出各种信息,用户空间工具
|
||||
如top(1)使用这些信息计算系统花费在某个特定状态的平均时间。
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :ref:`Documentation/admin-guide/index.rst`
|
||||
:Original: :doc:`../../../admin-guide/index`
|
||||
:Translator: Alex Shi <alex.shi@linux.alibaba.com>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11993,7 +11993,8 @@ F: include/uapi/linux/netrom.h
|
|||
F: net/netrom/
|
||||
|
||||
NETRONOME ETHERNET DRIVERS
|
||||
M: Jakub Kicinski <kuba@kernel.org>
|
||||
M: Simon Horman <simon.horman@netronome.com>
|
||||
R: Jakub Kicinski <kuba@kernel.org>
|
||||
L: oss-drivers@netronome.com
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/netronome/
|
||||
|
|
|
|||
|
|
@ -7,5 +7,4 @@ obj-$(CONFIG_S390_HYPFS_FS) += hypfs/
|
|||
obj-$(CONFIG_APPLDATA_BASE) += appldata/
|
||||
obj-y += net/
|
||||
obj-$(CONFIG_PCI) += pci/
|
||||
obj-$(CONFIG_NUMA) += numa/
|
||||
obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += purgatory/
|
||||
|
|
|
|||
|
|
@ -126,7 +126,6 @@ config S390
|
|||
select HAVE_ARCH_JUMP_LABEL_RELATIVE
|
||||
select HAVE_ARCH_KASAN
|
||||
select HAVE_ARCH_KASAN_VMALLOC
|
||||
select CLOCKSOURCE_VALIDATE_LAST_CYCLE
|
||||
select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_SOFT_DIRTY
|
||||
|
|
@ -766,6 +765,7 @@ config VFIO_AP
|
|||
def_tristate n
|
||||
prompt "VFIO support for AP devices"
|
||||
depends on S390_AP_IOMMU && VFIO_MDEV_DEVICE && KVM
|
||||
depends on ZCRYPT
|
||||
help
|
||||
This driver grants access to Adjunct Processor (AP) devices
|
||||
via the VFIO mediated device interface.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,11 @@ static inline int atomic_fetch_add(int i, atomic_t *v)
|
|||
static inline void atomic_add(int i, atomic_t *v)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
|
||||
if (__builtin_constant_p(i) && (i > -129) && (i < 128)) {
|
||||
/*
|
||||
* Order of conditions is important to circumvent gcc 10 bug:
|
||||
* https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549318.html
|
||||
*/
|
||||
if ((i > -129) && (i < 128) && __builtin_constant_p(i)) {
|
||||
__atomic_add_const(i, &v->counter);
|
||||
return;
|
||||
}
|
||||
|
|
@ -112,7 +116,11 @@ static inline s64 atomic64_fetch_add(s64 i, atomic64_t *v)
|
|||
static inline void atomic64_add(s64 i, atomic64_t *v)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
|
||||
if (__builtin_constant_p(i) && (i > -129) && (i < 128)) {
|
||||
/*
|
||||
* Order of conditions is important to circumvent gcc 10 bug:
|
||||
* https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549318.html
|
||||
*/
|
||||
if ((i > -129) && (i < 128) && __builtin_constant_p(i)) {
|
||||
__atomic64_add_const(i, (long *)&v->counter);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* S/390 debug facility
|
||||
*
|
||||
* Copyright IBM Corp. 1999, 2000
|
||||
* Copyright IBM Corp. 1999, 2020
|
||||
*/
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
|
@ -26,19 +26,14 @@
|
|||
#define DEBUG_DATA(entry) (char *)(entry + 1) /* data is stored behind */
|
||||
/* the entry information */
|
||||
|
||||
#define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */
|
||||
#define __DEBUG_FEATURE_VERSION 3 /* version of debug feature */
|
||||
|
||||
struct __debug_entry {
|
||||
union {
|
||||
struct {
|
||||
unsigned long clock : 52;
|
||||
unsigned long exception : 1;
|
||||
unsigned long level : 3;
|
||||
unsigned long cpuid : 8;
|
||||
} fields;
|
||||
unsigned long stck;
|
||||
} id;
|
||||
unsigned long clock : 60;
|
||||
unsigned long exception : 1;
|
||||
unsigned long level : 3;
|
||||
void *caller;
|
||||
unsigned short cpu;
|
||||
} __packed;
|
||||
|
||||
typedef struct __debug_entry debug_entry_t;
|
||||
|
|
|
|||
|
|
@ -86,12 +86,6 @@ static inline const struct cpumask *cpumask_of_node(int node)
|
|||
|
||||
#define pcibus_to_node(bus) __pcibus_to_node(bus)
|
||||
|
||||
#define node_distance(a, b) __node_distance(a, b)
|
||||
static inline int __node_distance(int a, int b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_NUMA */
|
||||
|
||||
#define numa_node_id numa_node_id
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE)
|
|||
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
obj-$(CONFIG_SCHED_TOPOLOGY) += topology.o
|
||||
obj-$(CONFIG_NUMA) += numa.o
|
||||
obj-$(CONFIG_AUDIT) += audit.o
|
||||
compat-obj-$(CONFIG_AUDIT) += compat_audit.o
|
||||
obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* S/390 debug facility
|
||||
*
|
||||
* Copyright IBM Corp. 1999, 2012
|
||||
* Copyright IBM Corp. 1999, 2020
|
||||
*
|
||||
* Author(s): Michael Holzheu (holzheu@de.ibm.com),
|
||||
* Holger Smolinski (Holger.Smolinski@de.ibm.com)
|
||||
|
|
@ -433,7 +433,7 @@ static int debug_format_entry(file_private_info_t *p_info)
|
|||
act_entry = (debug_entry_t *) ((char *)id_snap->areas[p_info->act_area]
|
||||
[p_info->act_page] + p_info->act_entry);
|
||||
|
||||
if (act_entry->id.stck == 0LL)
|
||||
if (act_entry->clock == 0LL)
|
||||
goto out; /* empty entry */
|
||||
if (view->header_proc)
|
||||
len += view->header_proc(id_snap, view, p_info->act_area,
|
||||
|
|
@ -829,12 +829,17 @@ static inline debug_entry_t *get_active_entry(debug_info_t *id)
|
|||
static inline void debug_finish_entry(debug_info_t *id, debug_entry_t *active,
|
||||
int level, int exception)
|
||||
{
|
||||
active->id.stck = get_tod_clock_fast() -
|
||||
*(unsigned long long *) &tod_clock_base[1];
|
||||
active->id.fields.cpuid = smp_processor_id();
|
||||
unsigned char clk[STORE_CLOCK_EXT_SIZE];
|
||||
unsigned long timestamp;
|
||||
|
||||
get_tod_clock_ext(clk);
|
||||
timestamp = *(unsigned long *) &clk[0] >> 4;
|
||||
timestamp -= TOD_UNIX_EPOCH >> 12;
|
||||
active->clock = timestamp;
|
||||
active->cpu = smp_processor_id();
|
||||
active->caller = __builtin_return_address(0);
|
||||
active->id.fields.exception = exception;
|
||||
active->id.fields.level = level;
|
||||
active->exception = exception;
|
||||
active->level = level;
|
||||
proceed_active_entry(id);
|
||||
if (exception)
|
||||
proceed_active_area(id);
|
||||
|
|
@ -1398,25 +1403,24 @@ static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view,
|
|||
int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view,
|
||||
int area, debug_entry_t *entry, char *out_buf)
|
||||
{
|
||||
unsigned long base, sec, usec;
|
||||
unsigned long sec, usec;
|
||||
unsigned long caller;
|
||||
unsigned int level;
|
||||
char *except_str;
|
||||
int rc = 0;
|
||||
|
||||
level = entry->id.fields.level;
|
||||
base = (*(unsigned long *) &tod_clock_base[0]) >> 4;
|
||||
sec = (entry->id.stck >> 12) + base - (TOD_UNIX_EPOCH >> 12);
|
||||
level = entry->level;
|
||||
sec = entry->clock;
|
||||
usec = do_div(sec, USEC_PER_SEC);
|
||||
|
||||
if (entry->id.fields.exception)
|
||||
if (entry->exception)
|
||||
except_str = "*";
|
||||
else
|
||||
except_str = "-";
|
||||
caller = (unsigned long) entry->caller;
|
||||
rc += sprintf(out_buf, "%02i %011ld:%06lu %1u %1s %02i %pK ",
|
||||
rc += sprintf(out_buf, "%02i %011ld:%06lu %1u %1s %04u %pK ",
|
||||
area, sec, usec, level, except_str,
|
||||
entry->id.fields.cpuid, (void *)caller);
|
||||
entry->cpu, (void *)caller);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(debug_dflt_header_fn);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs,
|
|||
break;
|
||||
if (state.reliable && !addr) {
|
||||
pr_err("unwind state reliable but addr is 0\n");
|
||||
kfree(bt);
|
||||
return -EINVAL;
|
||||
}
|
||||
sprint_symbol(sym, addr);
|
||||
|
|
|
|||
|
|
@ -2485,23 +2485,36 @@ void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long bitmap[4],
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(gmap_sync_dirty_log_pmd);
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
static int thp_split_walk_pmd_entry(pmd_t *pmd, unsigned long addr,
|
||||
unsigned long end, struct mm_walk *walk)
|
||||
{
|
||||
struct vm_area_struct *vma = walk->vma;
|
||||
|
||||
split_huge_pmd(vma, pmd, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mm_walk_ops thp_split_walk_ops = {
|
||||
.pmd_entry = thp_split_walk_pmd_entry,
|
||||
};
|
||||
|
||||
static inline void thp_split_mm(struct mm_struct *mm)
|
||||
{
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long addr;
|
||||
|
||||
for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
|
||||
for (addr = vma->vm_start;
|
||||
addr < vma->vm_end;
|
||||
addr += PAGE_SIZE)
|
||||
follow_page(vma, addr, FOLL_SPLIT);
|
||||
vma->vm_flags &= ~VM_HUGEPAGE;
|
||||
vma->vm_flags |= VM_NOHUGEPAGE;
|
||||
walk_page_vma(vma, &thp_split_walk_ops, NULL);
|
||||
}
|
||||
mm->def_flags |= VM_NOHUGEPAGE;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static inline void thp_split_mm(struct mm_struct *mm)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
|
||||
/*
|
||||
* Remove all empty zero pages from the mapping for lazy refaulting
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-y += numa.o
|
||||
|
|
@ -542,8 +542,8 @@ int i2c_pca_add_numbered_bus(struct i2c_adapter *adap)
|
|||
}
|
||||
EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
|
||||
|
||||
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
|
||||
"Wolfram Sang <kernel@pengutronix.de>");
|
||||
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
|
||||
MODULE_AUTHOR("Wolfram Sang <kernel@pengutronix.de>");
|
||||
MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ config I2C_I801
|
|||
Elkhart Lake (PCH)
|
||||
Tiger Lake (PCH)
|
||||
Jasper Lake (SOC)
|
||||
Emmitsburg (PCH)
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called i2c-i801.
|
||||
|
|
|
|||
|
|
@ -519,9 +519,9 @@ static struct pci_driver ali1535_driver = {
|
|||
|
||||
module_pci_driver(ali1535_driver);
|
||||
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
|
||||
"Philip Edelbrock <phil@netroedge.com>, "
|
||||
"Mark D. Studebaker <mdsxyz123@yahoo.com> "
|
||||
"and Dan Eaton <dan.eaton@rocketlogix.com>");
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
|
||||
MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
|
||||
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
|
||||
MODULE_AUTHOR("Dan Eaton <dan.eaton@rocketlogix.com>");
|
||||
MODULE_DESCRIPTION("ALI1535 SMBus driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -502,8 +502,8 @@ static struct pci_driver ali15x3_driver = {
|
|||
|
||||
module_pci_driver(ali15x3_driver);
|
||||
|
||||
MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, "
|
||||
"Philip Edelbrock <phil@netroedge.com>, "
|
||||
"and Mark D. Studebaker <mdsxyz123@yahoo.com>");
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
|
||||
MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
|
||||
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
|
||||
MODULE_DESCRIPTION("ALI15X3 SMBus driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
|
|||
if (status)
|
||||
return status;
|
||||
len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
for (i = 0; i < len; i++) {
|
||||
status = amd_ec_read(smbus, AMD_SMB_DATA + i,
|
||||
|
|
|
|||
|
|
@ -504,7 +504,7 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
|
|||
goto error_and_stop;
|
||||
}
|
||||
irq_handled |= ASPEED_I2CD_INTR_TX_ACK;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case ASPEED_I2C_MASTER_TX_FIRST:
|
||||
if (bus->buf_index < msg->len) {
|
||||
bus->master_state = ASPEED_I2C_MASTER_TX;
|
||||
|
|
@ -520,7 +520,7 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
|
|||
/* RX may not have completed yet (only address cycle) */
|
||||
if (!(irq_status & ASPEED_I2CD_INTR_RX_DONE))
|
||||
goto out_no_complete;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case ASPEED_I2C_MASTER_RX:
|
||||
if (unlikely(!(irq_status & ASPEED_I2CD_INTR_RX_DONE))) {
|
||||
dev_err(bus->dev, "master failed to RX\n");
|
||||
|
|
|
|||
|
|
@ -816,79 +816,16 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void at91_prepare_twi_recovery(struct i2c_adapter *adap)
|
||||
{
|
||||
struct at91_twi_dev *dev = i2c_get_adapdata(adap);
|
||||
|
||||
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_gpio);
|
||||
}
|
||||
|
||||
static void at91_unprepare_twi_recovery(struct i2c_adapter *adap)
|
||||
{
|
||||
struct at91_twi_dev *dev = i2c_get_adapdata(adap);
|
||||
|
||||
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
|
||||
}
|
||||
|
||||
static int at91_init_twi_recovery_gpio(struct platform_device *pdev,
|
||||
struct at91_twi_dev *dev)
|
||||
{
|
||||
struct i2c_bus_recovery_info *rinfo = &dev->rinfo;
|
||||
|
||||
dev->pinctrl = devm_pinctrl_get(&pdev->dev);
|
||||
if (!dev->pinctrl || IS_ERR(dev->pinctrl)) {
|
||||
rinfo->pinctrl = devm_pinctrl_get(&pdev->dev);
|
||||
if (!rinfo->pinctrl || IS_ERR(rinfo->pinctrl)) {
|
||||
dev_info(dev->dev, "can't get pinctrl, bus recovery not supported\n");
|
||||
return PTR_ERR(dev->pinctrl);
|
||||
return PTR_ERR(rinfo->pinctrl);
|
||||
}
|
||||
|
||||
dev->pinctrl_pins_default = pinctrl_lookup_state(dev->pinctrl,
|
||||
PINCTRL_STATE_DEFAULT);
|
||||
dev->pinctrl_pins_gpio = pinctrl_lookup_state(dev->pinctrl,
|
||||
"gpio");
|
||||
if (IS_ERR(dev->pinctrl_pins_default) ||
|
||||
IS_ERR(dev->pinctrl_pins_gpio)) {
|
||||
dev_info(&pdev->dev, "pinctrl states incomplete for recovery\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* pins will be taken as GPIO, so we might as well inform pinctrl about
|
||||
* this and move the state to GPIO
|
||||
*/
|
||||
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_gpio);
|
||||
|
||||
rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN);
|
||||
if (PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
rinfo->scl_gpiod = devm_gpiod_get(&pdev->dev, "scl",
|
||||
GPIOD_OUT_HIGH_OPEN_DRAIN);
|
||||
if (PTR_ERR(rinfo->scl_gpiod) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (IS_ERR(rinfo->sda_gpiod) ||
|
||||
IS_ERR(rinfo->scl_gpiod)) {
|
||||
dev_info(&pdev->dev, "recovery information incomplete\n");
|
||||
if (!IS_ERR(rinfo->sda_gpiod)) {
|
||||
gpiod_put(rinfo->sda_gpiod);
|
||||
rinfo->sda_gpiod = NULL;
|
||||
}
|
||||
if (!IS_ERR(rinfo->scl_gpiod)) {
|
||||
gpiod_put(rinfo->scl_gpiod);
|
||||
rinfo->scl_gpiod = NULL;
|
||||
}
|
||||
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* change the state of the pins back to their default state */
|
||||
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
|
||||
|
||||
dev_info(&pdev->dev, "using scl, sda for recovery\n");
|
||||
|
||||
rinfo->prepare_recovery = at91_prepare_twi_recovery;
|
||||
rinfo->unprepare_recovery = at91_unprepare_twi_recovery;
|
||||
rinfo->recover_bus = i2c_generic_scl_recovery;
|
||||
dev->adapter.bus_recovery_info = rinfo;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -157,9 +157,6 @@ struct at91_twi_dev {
|
|||
struct at91_twi_dma dma;
|
||||
bool slave_detected;
|
||||
struct i2c_bus_recovery_info rinfo;
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state *pinctrl_pins_default;
|
||||
struct pinctrl_state *pinctrl_pins_gpio;
|
||||
#ifdef CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL
|
||||
unsigned smr;
|
||||
struct i2c_client *slave;
|
||||
|
|
|
|||
|
|
@ -1078,7 +1078,7 @@ static int bcm_iproc_i2c_unreg_slave(struct i2c_client *slave)
|
|||
if (!iproc_i2c->slave)
|
||||
return -EINVAL;
|
||||
|
||||
iproc_i2c->slave = NULL;
|
||||
disable_irq(iproc_i2c->irq);
|
||||
|
||||
/* disable all slave interrupts */
|
||||
tmp = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET);
|
||||
|
|
@ -1091,6 +1091,17 @@ static int bcm_iproc_i2c_unreg_slave(struct i2c_client *slave)
|
|||
tmp &= ~BIT(S_CFG_EN_NIC_SMB_ADDR3_SHIFT);
|
||||
iproc_i2c_wr_reg(iproc_i2c, S_CFG_SMBUS_ADDR_OFFSET, tmp);
|
||||
|
||||
/* flush TX/RX FIFOs */
|
||||
tmp = (BIT(S_FIFO_RX_FLUSH_SHIFT) | BIT(S_FIFO_TX_FLUSH_SHIFT));
|
||||
iproc_i2c_wr_reg(iproc_i2c, S_FIFO_CTRL_OFFSET, tmp);
|
||||
|
||||
/* clear all pending slave interrupts */
|
||||
iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, ISR_MASK_SLAVE);
|
||||
|
||||
iproc_i2c->slave = NULL;
|
||||
|
||||
enable_irq(iproc_i2c->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ static const struct i2c_algorithm bcm2835_i2c_algo = {
|
|||
|
||||
/*
|
||||
* The BCM2835 was reported to have problems with clock stretching:
|
||||
* http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
|
||||
* https://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
|
||||
* https://www.raspberrypi.org/forums/viewtopic.php?p=146272
|
||||
*/
|
||||
static const struct i2c_adapter_quirks bcm2835_i2c_quirks = {
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
|
|||
switch (pdev->device) {
|
||||
case 0x0817:
|
||||
dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case 0x0818:
|
||||
case 0x0819:
|
||||
c->bus_num = pdev->device - 0x817 + 3;
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ static irqreturn_t dc_i2c_irq(int irq, void *dev_id)
|
|||
break;
|
||||
}
|
||||
i2c->state = STATE_WRITE;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case STATE_WRITE:
|
||||
if (i2c->msgbuf_ptr < i2c->msg->len)
|
||||
dc_i2c_write_buf(i2c);
|
||||
|
|
|
|||
|
|
@ -846,11 +846,10 @@ static void pch_i2c_remove(struct pci_dev *pdev)
|
|||
kfree(adap_info);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
static int __maybe_unused pch_i2c_suspend(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct adapter_info *adap_info = pci_get_drvdata(pdev);
|
||||
void __iomem *p = adap_info->pch_data[0].pch_base_address;
|
||||
|
||||
|
|
@ -872,34 +871,13 @@ static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
ioread32(p + PCH_I2CSR), ioread32(p + PCH_I2CBUFSTA),
|
||||
ioread32(p + PCH_I2CESRSTA));
|
||||
|
||||
ret = pci_save_state(pdev);
|
||||
|
||||
if (ret) {
|
||||
pch_pci_err(pdev, "pci_save_state\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||
pci_disable_device(pdev);
|
||||
pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pch_i2c_resume(struct pci_dev *pdev)
|
||||
static int __maybe_unused pch_i2c_resume(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
struct adapter_info *adap_info = pci_get_drvdata(pdev);
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
|
||||
if (pci_enable_device(pdev) < 0) {
|
||||
pch_pci_err(pdev, "pch_i2c_resume:pci_enable_device FAILED\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||
struct adapter_info *adap_info = dev_get_drvdata(dev);
|
||||
|
||||
for (i = 0; i < adap_info->ch_num; i++)
|
||||
pch_i2c_init(&adap_info->pch_data[i]);
|
||||
|
|
@ -908,18 +886,15 @@ static int pch_i2c_resume(struct pci_dev *pdev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define pch_i2c_suspend NULL
|
||||
#define pch_i2c_resume NULL
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(pch_i2c_pm_ops, pch_i2c_suspend, pch_i2c_resume);
|
||||
|
||||
static struct pci_driver pch_pcidriver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = pch_pcidev_id,
|
||||
.probe = pch_i2c_probe,
|
||||
.remove = pch_i2c_remove,
|
||||
.suspend = pch_i2c_suspend,
|
||||
.resume = pch_i2c_resume
|
||||
.driver.pm = &pch_i2c_pm_ops,
|
||||
};
|
||||
|
||||
module_pci_driver(pch_pcidriver);
|
||||
|
|
|
|||
|
|
@ -442,6 +442,7 @@ static struct platform_driver em_i2c_driver = {
|
|||
module_platform_driver(em_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("EMEV2 I2C bus driver");
|
||||
MODULE_AUTHOR("Ian Molton and Wolfram Sang <wsa@sang-engineering.com>");
|
||||
MODULE_AUTHOR("Ian Molton");
|
||||
MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DEVICE_TABLE(of, em_i2c_ids);
|
||||
|
|
|
|||
|
|
@ -703,7 +703,7 @@ static int fsi_i2c_probe(struct device *dev)
|
|||
|
||||
for (port_no = 0; port_no < ports; port_no++) {
|
||||
np = fsi_i2c_find_port_of_node(dev->of_node, port_no);
|
||||
if (np && !of_device_is_available(np))
|
||||
if (!of_device_is_available(np))
|
||||
continue;
|
||||
|
||||
port = kzalloc(sizeof(*port), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
* Sunrise Point-H (PCH) 0xa123 32 hard yes yes yes
|
||||
* Sunrise Point-LP (PCH) 0x9d23 32 hard yes yes yes
|
||||
* DNV (SOC) 0x19df 32 hard yes yes yes
|
||||
* Emmitsburg (PCH) 0x1bc9 32 hard yes yes yes
|
||||
* Broxton (SOC) 0x5ad4 32 hard yes yes yes
|
||||
* Lewisburg (PCH) 0xa1a3 32 hard yes yes yes
|
||||
* Lewisburg Supersku (PCH) 0xa223 32 hard yes yes yes
|
||||
|
|
@ -67,6 +68,7 @@
|
|||
* Comet Lake-H (PCH) 0x06a3 32 hard yes yes yes
|
||||
* Elkhart Lake (PCH) 0x4b23 32 hard yes yes yes
|
||||
* Tiger Lake-LP (PCH) 0xa0a3 32 hard yes yes yes
|
||||
* Tiger Lake-H (PCH) 0x43a3 32 hard yes yes yes
|
||||
* Jasper Lake (SOC) 0x4da3 32 hard yes yes yes
|
||||
* Comet Lake-V (PCH) 0xa3a3 32 hard yes yes yes
|
||||
*
|
||||
|
|
@ -207,6 +209,7 @@
|
|||
#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12
|
||||
#define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df
|
||||
#define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df
|
||||
#define PCI_DEVICE_ID_INTEL_EBG_SMBUS 0x1bc9
|
||||
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
|
||||
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
|
||||
/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
|
||||
|
|
@ -221,6 +224,7 @@
|
|||
#define PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS 0x31d4
|
||||
#define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS 0x34a3
|
||||
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
|
||||
#define PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS 0x43a3
|
||||
#define PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS 0x4b23
|
||||
#define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS 0x4da3
|
||||
#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4
|
||||
|
|
@ -1062,6 +1066,7 @@ static const struct pci_device_id i801_ids[] = {
|
|||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CDF_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EBG_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROXTON_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS) },
|
||||
|
|
@ -1074,6 +1079,7 @@ static const struct pci_device_id i801_ids[] = {
|
|||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS) },
|
||||
{ 0, }
|
||||
};
|
||||
|
|
@ -1748,7 +1754,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
case PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS:
|
||||
case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS:
|
||||
case PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS:
|
||||
case PCI_DEVICE_ID_INTEL_TIGERLAKE_H_SMBUS:
|
||||
case PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS:
|
||||
case PCI_DEVICE_ID_INTEL_EBG_SMBUS:
|
||||
priv->features |= FEATURE_BLOCK_PROC;
|
||||
priv->features |= FEATURE_I2C_BLOCK_READ;
|
||||
priv->features |= FEATURE_IRQ;
|
||||
|
|
@ -1765,19 +1773,19 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1:
|
||||
case PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2:
|
||||
priv->features |= FEATURE_IDF;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
default:
|
||||
priv->features |= FEATURE_BLOCK_PROC;
|
||||
priv->features |= FEATURE_I2C_BLOCK_READ;
|
||||
priv->features |= FEATURE_IRQ;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case PCI_DEVICE_ID_INTEL_82801DB_3:
|
||||
priv->features |= FEATURE_SMBUS_PEC;
|
||||
priv->features |= FEATURE_BLOCK_BUFFER;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case PCI_DEVICE_ID_INTEL_82801CA_3:
|
||||
priv->features |= FEATURE_HOST_NOTIFY;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
case PCI_DEVICE_ID_INTEL_82801BA_2:
|
||||
case PCI_DEVICE_ID_INTEL_82801AB_3:
|
||||
case PCI_DEVICE_ID_INTEL_82801AA_3:
|
||||
|
|
@ -1986,7 +1994,8 @@ static void __exit i2c_i801_exit(void)
|
|||
pci_unregister_driver(&i801_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, Jean Delvare <jdelvare@suse.de>");
|
||||
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
|
||||
MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
|
||||
MODULE_DESCRIPTION("I801 SMBus driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
|||
|
|
@ -48,11 +48,13 @@
|
|||
|
||||
#define I2C_DMA_CON_TX 0x0000
|
||||
#define I2C_DMA_CON_RX 0x0001
|
||||
#define I2C_DMA_ASYNC_MODE 0x0004
|
||||
#define I2C_DMA_SKIP_CONFIG 0x0010
|
||||
#define I2C_DMA_DIR_CHANGE 0x0200
|
||||
#define I2C_DMA_START_EN 0x0001
|
||||
#define I2C_DMA_INT_FLAG_NONE 0x0000
|
||||
#define I2C_DMA_CLR_FLAG 0x0000
|
||||
#define I2C_DMA_HARD_RST 0x0002
|
||||
#define I2C_DMA_4G_MODE 0x0001
|
||||
|
||||
#define MAX_SAMPLE_CNT_DIV 8
|
||||
#define MAX_STEP_CNT_DIV 64
|
||||
|
|
@ -201,10 +203,11 @@ struct mtk_i2c_compatible {
|
|||
unsigned char dcm: 1;
|
||||
unsigned char auto_restart: 1;
|
||||
unsigned char aux_len_reg: 1;
|
||||
unsigned char support_33bits: 1;
|
||||
unsigned char timing_adjust: 1;
|
||||
unsigned char dma_sync: 1;
|
||||
unsigned char ltiming_adjust: 1;
|
||||
unsigned char apdma_sync: 1;
|
||||
unsigned char max_dma_support;
|
||||
};
|
||||
|
||||
struct mtk_i2c_ac_timing {
|
||||
|
|
@ -250,14 +253,13 @@ struct mtk_i2c {
|
|||
|
||||
/**
|
||||
* struct i2c_spec_values:
|
||||
* min_low_ns: min LOW period of the SCL clock
|
||||
* min_su_sta_ns: min set-up time for a repeated START condition
|
||||
* max_hd_dat_ns: max data hold time
|
||||
* min_su_dat_ns: min data set-up time
|
||||
* @min_low_ns: min LOW period of the SCL clock
|
||||
* @min_su_sta_ns: min set-up time for a repeated START condition
|
||||
* @max_hd_dat_ns: max data hold time
|
||||
* @min_su_dat_ns: min data set-up time
|
||||
*/
|
||||
struct i2c_spec_values {
|
||||
unsigned int min_low_ns;
|
||||
unsigned int min_high_ns;
|
||||
unsigned int min_su_sta_ns;
|
||||
unsigned int max_hd_dat_ns;
|
||||
unsigned int min_su_dat_ns;
|
||||
|
|
@ -307,10 +309,11 @@ static const struct mtk_i2c_compatible mt2712_compat = {
|
|||
.dcm = 1,
|
||||
.auto_restart = 1,
|
||||
.aux_len_reg = 1,
|
||||
.support_33bits = 1,
|
||||
.timing_adjust = 1,
|
||||
.dma_sync = 0,
|
||||
.ltiming_adjust = 0,
|
||||
.apdma_sync = 0,
|
||||
.max_dma_support = 33,
|
||||
};
|
||||
|
||||
static const struct mtk_i2c_compatible mt6577_compat = {
|
||||
|
|
@ -320,10 +323,11 @@ static const struct mtk_i2c_compatible mt6577_compat = {
|
|||
.dcm = 1,
|
||||
.auto_restart = 0,
|
||||
.aux_len_reg = 0,
|
||||
.support_33bits = 0,
|
||||
.timing_adjust = 0,
|
||||
.dma_sync = 0,
|
||||
.ltiming_adjust = 0,
|
||||
.apdma_sync = 0,
|
||||
.max_dma_support = 32,
|
||||
};
|
||||
|
||||
static const struct mtk_i2c_compatible mt6589_compat = {
|
||||
|
|
@ -333,10 +337,11 @@ static const struct mtk_i2c_compatible mt6589_compat = {
|
|||
.dcm = 0,
|
||||
.auto_restart = 0,
|
||||
.aux_len_reg = 0,
|
||||
.support_33bits = 0,
|
||||
.timing_adjust = 0,
|
||||
.dma_sync = 0,
|
||||
.ltiming_adjust = 0,
|
||||
.apdma_sync = 0,
|
||||
.max_dma_support = 32,
|
||||
};
|
||||
|
||||
static const struct mtk_i2c_compatible mt7622_compat = {
|
||||
|
|
@ -346,10 +351,11 @@ static const struct mtk_i2c_compatible mt7622_compat = {
|
|||
.dcm = 1,
|
||||
.auto_restart = 1,
|
||||
.aux_len_reg = 1,
|
||||
.support_33bits = 0,
|
||||
.timing_adjust = 0,
|
||||
.dma_sync = 0,
|
||||
.ltiming_adjust = 0,
|
||||
.apdma_sync = 0,
|
||||
.max_dma_support = 32,
|
||||
};
|
||||
|
||||
static const struct mtk_i2c_compatible mt8173_compat = {
|
||||
|
|
@ -358,10 +364,11 @@ static const struct mtk_i2c_compatible mt8173_compat = {
|
|||
.dcm = 1,
|
||||
.auto_restart = 1,
|
||||
.aux_len_reg = 1,
|
||||
.support_33bits = 1,
|
||||
.timing_adjust = 0,
|
||||
.dma_sync = 0,
|
||||
.ltiming_adjust = 0,
|
||||
.apdma_sync = 0,
|
||||
.max_dma_support = 33,
|
||||
};
|
||||
|
||||
static const struct mtk_i2c_compatible mt8183_compat = {
|
||||
|
|
@ -371,10 +378,25 @@ static const struct mtk_i2c_compatible mt8183_compat = {
|
|||
.dcm = 0,
|
||||
.auto_restart = 1,
|
||||
.aux_len_reg = 1,
|
||||
.support_33bits = 1,
|
||||
.timing_adjust = 1,
|
||||
.dma_sync = 1,
|
||||
.ltiming_adjust = 1,
|
||||
.apdma_sync = 0,
|
||||
.max_dma_support = 33,
|
||||
};
|
||||
|
||||
static const struct mtk_i2c_compatible mt8192_compat = {
|
||||
.quirks = &mt8183_i2c_quirks,
|
||||
.regs = mt_i2c_regs_v2,
|
||||
.pmic_i2c = 0,
|
||||
.dcm = 0,
|
||||
.auto_restart = 1,
|
||||
.aux_len_reg = 1,
|
||||
.timing_adjust = 1,
|
||||
.dma_sync = 1,
|
||||
.ltiming_adjust = 1,
|
||||
.apdma_sync = 1,
|
||||
.max_dma_support = 36,
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_i2c_of_match[] = {
|
||||
|
|
@ -384,6 +406,7 @@ static const struct of_device_id mtk_i2c_of_match[] = {
|
|||
{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
|
||||
{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
|
||||
{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
|
||||
{ .compatible = "mediatek,mt8192-i2c", .data = &mt8192_compat },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_i2c_of_match);
|
||||
|
|
@ -786,11 +809,6 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 mtk_i2c_set_4g_mode(dma_addr_t addr)
|
||||
{
|
||||
return (addr & BIT_ULL(32)) ? I2C_DMA_4G_MODE : I2C_DMA_CLR_FLAG;
|
||||
}
|
||||
|
||||
static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
||||
int num, int left_num)
|
||||
{
|
||||
|
|
@ -798,6 +816,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
|||
u16 start_reg;
|
||||
u16 control_reg;
|
||||
u16 restart_flag = 0;
|
||||
u16 dma_sync = 0;
|
||||
u32 reg_4g_mode;
|
||||
u8 *dma_rd_buf = NULL;
|
||||
u8 *dma_wr_buf = NULL;
|
||||
|
|
@ -851,10 +870,16 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
|||
mtk_i2c_writew(i2c, num, OFFSET_TRANSAC_LEN);
|
||||
}
|
||||
|
||||
if (i2c->dev_comp->apdma_sync) {
|
||||
dma_sync = I2C_DMA_SKIP_CONFIG | I2C_DMA_ASYNC_MODE;
|
||||
if (i2c->op == I2C_MASTER_WRRD)
|
||||
dma_sync |= I2C_DMA_DIR_CHANGE;
|
||||
}
|
||||
|
||||
/* Prepare buffer data to start transfer */
|
||||
if (i2c->op == I2C_MASTER_RD) {
|
||||
writel(I2C_DMA_INT_FLAG_NONE, i2c->pdmabase + OFFSET_INT_FLAG);
|
||||
writel(I2C_DMA_CON_RX, i2c->pdmabase + OFFSET_CON);
|
||||
writel(I2C_DMA_CON_RX | dma_sync, i2c->pdmabase + OFFSET_CON);
|
||||
|
||||
dma_rd_buf = i2c_get_dma_safe_msg_buf(msgs, 1);
|
||||
if (!dma_rd_buf)
|
||||
|
|
@ -868,8 +893,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (i2c->dev_comp->support_33bits) {
|
||||
reg_4g_mode = mtk_i2c_set_4g_mode(rpaddr);
|
||||
if (i2c->dev_comp->max_dma_support > 32) {
|
||||
reg_4g_mode = upper_32_bits(rpaddr);
|
||||
writel(reg_4g_mode, i2c->pdmabase + OFFSET_RX_4G_MODE);
|
||||
}
|
||||
|
||||
|
|
@ -877,7 +902,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
|||
writel(msgs->len, i2c->pdmabase + OFFSET_RX_LEN);
|
||||
} else if (i2c->op == I2C_MASTER_WR) {
|
||||
writel(I2C_DMA_INT_FLAG_NONE, i2c->pdmabase + OFFSET_INT_FLAG);
|
||||
writel(I2C_DMA_CON_TX, i2c->pdmabase + OFFSET_CON);
|
||||
writel(I2C_DMA_CON_TX | dma_sync, i2c->pdmabase + OFFSET_CON);
|
||||
|
||||
dma_wr_buf = i2c_get_dma_safe_msg_buf(msgs, 1);
|
||||
if (!dma_wr_buf)
|
||||
|
|
@ -891,8 +916,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (i2c->dev_comp->support_33bits) {
|
||||
reg_4g_mode = mtk_i2c_set_4g_mode(wpaddr);
|
||||
if (i2c->dev_comp->max_dma_support > 32) {
|
||||
reg_4g_mode = upper_32_bits(wpaddr);
|
||||
writel(reg_4g_mode, i2c->pdmabase + OFFSET_TX_4G_MODE);
|
||||
}
|
||||
|
||||
|
|
@ -900,7 +925,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
|||
writel(msgs->len, i2c->pdmabase + OFFSET_TX_LEN);
|
||||
} else {
|
||||
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_INT_FLAG);
|
||||
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_CON);
|
||||
writel(I2C_DMA_CLR_FLAG | dma_sync, i2c->pdmabase + OFFSET_CON);
|
||||
|
||||
dma_wr_buf = i2c_get_dma_safe_msg_buf(msgs, 1);
|
||||
if (!dma_wr_buf)
|
||||
|
|
@ -937,11 +962,11 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (i2c->dev_comp->support_33bits) {
|
||||
reg_4g_mode = mtk_i2c_set_4g_mode(wpaddr);
|
||||
if (i2c->dev_comp->max_dma_support > 32) {
|
||||
reg_4g_mode = upper_32_bits(wpaddr);
|
||||
writel(reg_4g_mode, i2c->pdmabase + OFFSET_TX_4G_MODE);
|
||||
|
||||
reg_4g_mode = mtk_i2c_set_4g_mode(rpaddr);
|
||||
reg_4g_mode = upper_32_bits(rpaddr);
|
||||
writel(reg_4g_mode, i2c->pdmabase + OFFSET_RX_4G_MODE);
|
||||
}
|
||||
|
||||
|
|
@ -1215,8 +1240,9 @@ static int mtk_i2c_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (i2c->dev_comp->support_33bits) {
|
||||
ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(33));
|
||||
if (i2c->dev_comp->max_dma_support > 32) {
|
||||
ret = dma_set_mask(&pdev->dev,
|
||||
DMA_BIT_MASK(i2c->dev_comp->max_dma_support));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "dma_set_mask return error.\n");
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
|
|||
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
fallthrough;
|
||||
case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
|
||||
case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
|
||||
if ((drv_data->bytes_left == 0)
|
||||
|
|
@ -282,14 +282,14 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
|
|||
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
fallthrough;
|
||||
case MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK: /* 0xe0 */
|
||||
if (drv_data->bytes_left == 0) {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
|
||||
drv_data->state = MV64XXX_I2C_STATE_IDLE;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
fallthrough;
|
||||
case MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK: /* 0x50 */
|
||||
if (status != MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK)
|
||||
drv_data->action = MV64XXX_I2C_ACTION_CONTINUE;
|
||||
|
|
@ -417,8 +417,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
|
|||
"mv64xxx_i2c_do_action: Invalid action: %d\n",
|
||||
drv_data->action);
|
||||
drv_data->rc = -EIO;
|
||||
|
||||
/* FALLTHRU */
|
||||
fallthrough;
|
||||
case MV64XXX_I2C_ACTION_SEND_STOP:
|
||||
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
|
||||
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
|
||||
|
|
|
|||
|
|
@ -1122,6 +1122,7 @@ static void __exit nmk_i2c_exit(void)
|
|||
subsys_initcall(nmk_i2c_init);
|
||||
module_exit(nmk_i2c_exit);
|
||||
|
||||
MODULE_AUTHOR("Sachin Verma, Srinidhi KASAGAR");
|
||||
MODULE_AUTHOR("Sachin Verma");
|
||||
MODULE_AUTHOR("Srinidhi KASAGAR");
|
||||
MODULE_DESCRIPTION("Nomadik/Ux500 I2C driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -1032,7 +1032,7 @@ static struct pci_driver piix4_driver = {
|
|||
|
||||
module_pci_driver(piix4_driver);
|
||||
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
|
||||
"Philip Edelbrock <phil@netroedge.com>");
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
|
||||
MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
|
||||
MODULE_DESCRIPTION("PIIX4 SMBus driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -781,7 +781,8 @@ static void __exit i2c_adap_pnx_exit(void)
|
|||
platform_driver_unregister(&i2c_pnx_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
|
||||
MODULE_AUTHOR("Vitaly Wool");
|
||||
MODULE_AUTHOR("Dennis Kovalev <source@mvista.com>");
|
||||
MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:pnx-i2c");
|
||||
|
|
|
|||
|
|
@ -583,13 +583,14 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
|||
rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR);
|
||||
}
|
||||
|
||||
rcar_i2c_write(priv, ICSSR, ~SAR & 0xff);
|
||||
/* Clear SSR, too, because of old STOPs to other clients than us */
|
||||
rcar_i2c_write(priv, ICSSR, ~(SAR | SSR) & 0xff);
|
||||
}
|
||||
|
||||
/* master sent stop */
|
||||
if (ssr_filtered & SSR) {
|
||||
i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value);
|
||||
rcar_i2c_write(priv, ICSIER, SAR | SSR);
|
||||
rcar_i2c_write(priv, ICSIER, SAR);
|
||||
rcar_i2c_write(priv, ICSSR, ~SSR & 0xff);
|
||||
}
|
||||
|
||||
|
|
@ -853,7 +854,7 @@ static int rcar_reg_slave(struct i2c_client *slave)
|
|||
priv->slave = slave;
|
||||
rcar_i2c_write(priv, ICSAR, slave->addr);
|
||||
rcar_i2c_write(priv, ICSSR, 0);
|
||||
rcar_i2c_write(priv, ICSIER, SAR | SSR);
|
||||
rcar_i2c_write(priv, ICSIER, SAR);
|
||||
rcar_i2c_write(priv, ICSCR, SIE | SDBS);
|
||||
|
||||
return 0;
|
||||
|
|
@ -865,12 +866,14 @@ static int rcar_unreg_slave(struct i2c_client *slave)
|
|||
|
||||
WARN_ON(!priv->slave);
|
||||
|
||||
/* disable irqs and ensure none is running before clearing ptr */
|
||||
/* ensure no irq is running before clearing ptr */
|
||||
disable_irq(priv->irq);
|
||||
rcar_i2c_write(priv, ICSIER, 0);
|
||||
rcar_i2c_write(priv, ICSCR, 0);
|
||||
rcar_i2c_write(priv, ICSSR, 0);
|
||||
enable_irq(priv->irq);
|
||||
rcar_i2c_write(priv, ICSCR, SDBS);
|
||||
rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
|
||||
|
||||
synchronize_irq(priv->irq);
|
||||
priv->slave = NULL;
|
||||
|
||||
pm_runtime_put(rcar_i2c_priv_to_dev(priv));
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
|
@ -1040,8 +1041,21 @@ static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int num)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rk3x_i2c_xfer(struct i2c_adapter *adap,
|
||||
struct i2c_msg *msgs, int num)
|
||||
static int rk3x_i2c_wait_xfer_poll(struct rk3x_i2c *i2c)
|
||||
{
|
||||
ktime_t timeout = ktime_add_ms(ktime_get(), WAIT_TIMEOUT);
|
||||
|
||||
while (READ_ONCE(i2c->busy) &&
|
||||
ktime_compare(ktime_get(), timeout) < 0) {
|
||||
udelay(5);
|
||||
rk3x_i2c_irq(0, i2c);
|
||||
}
|
||||
|
||||
return !i2c->busy;
|
||||
}
|
||||
|
||||
static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
|
||||
struct i2c_msg *msgs, int num, bool polling)
|
||||
{
|
||||
struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data;
|
||||
unsigned long timeout, flags;
|
||||
|
|
@ -1075,8 +1089,12 @@ static int rk3x_i2c_xfer(struct i2c_adapter *adap,
|
|||
|
||||
rk3x_i2c_start(i2c);
|
||||
|
||||
timeout = wait_event_timeout(i2c->wait, !i2c->busy,
|
||||
msecs_to_jiffies(WAIT_TIMEOUT));
|
||||
if (!polling) {
|
||||
timeout = wait_event_timeout(i2c->wait, !i2c->busy,
|
||||
msecs_to_jiffies(WAIT_TIMEOUT));
|
||||
} else {
|
||||
timeout = rk3x_i2c_wait_xfer_poll(i2c);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&i2c->lock, flags);
|
||||
|
||||
|
|
@ -1110,6 +1128,18 @@ static int rk3x_i2c_xfer(struct i2c_adapter *adap,
|
|||
return ret < 0 ? ret : num;
|
||||
}
|
||||
|
||||
static int rk3x_i2c_xfer(struct i2c_adapter *adap,
|
||||
struct i2c_msg *msgs, int num)
|
||||
{
|
||||
return rk3x_i2c_xfer_common(adap, msgs, num, false);
|
||||
}
|
||||
|
||||
static int rk3x_i2c_xfer_polling(struct i2c_adapter *adap,
|
||||
struct i2c_msg *msgs, int num)
|
||||
{
|
||||
return rk3x_i2c_xfer_common(adap, msgs, num, true);
|
||||
}
|
||||
|
||||
static __maybe_unused int rk3x_i2c_resume(struct device *dev)
|
||||
{
|
||||
struct rk3x_i2c *i2c = dev_get_drvdata(dev);
|
||||
|
|
@ -1126,6 +1156,7 @@ static u32 rk3x_i2c_func(struct i2c_adapter *adap)
|
|||
|
||||
static const struct i2c_algorithm rk3x_i2c_algorithm = {
|
||||
.master_xfer = rk3x_i2c_xfer,
|
||||
.master_xfer_atomic = rk3x_i2c_xfer_polling,
|
||||
.functionality = rk3x_i2c_func,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -932,6 +932,7 @@ static void __exit sh_mobile_i2c_adap_exit(void)
|
|||
module_exit(sh_mobile_i2c_adap_exit);
|
||||
|
||||
MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver");
|
||||
MODULE_AUTHOR("Magnus Damm and Wolfram Sang");
|
||||
MODULE_AUTHOR("Magnus Damm");
|
||||
MODULE_AUTHOR("Wolfram Sang");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:i2c-sh_mobile");
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ static void __exit i2c_sibyte_exit(void)
|
|||
module_init(i2c_sibyte_init);
|
||||
module_exit(i2c_sibyte_exit);
|
||||
|
||||
MODULE_AUTHOR("Kip Walker (Broadcom Corp.), Steven J. Hill <sjhill@realitydiluted.com>");
|
||||
MODULE_AUTHOR("Kip Walker (Broadcom Corp.)");
|
||||
MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
|
||||
MODULE_DESCRIPTION("SMBus adapter routines for SiByte boards");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -470,6 +470,6 @@ static struct platform_driver i2c_sirfsoc_driver = {
|
|||
module_platform_driver(i2c_sirfsoc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("SiRF SoC I2C master controller driver");
|
||||
MODULE_AUTHOR("Zhiwu Song <Zhiwu.Song@csr.com>, "
|
||||
"Xiangzhen Ye <Xiangzhen.Ye@csr.com>");
|
||||
MODULE_AUTHOR("Zhiwu Song <Zhiwu.Song@csr.com>");
|
||||
MODULE_AUTHOR("Xiangzhen Ye <Xiangzhen.Ye@csr.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
|||
|
|
@ -398,8 +398,7 @@ static irqreturn_t synquacer_i2c_isr(int irq, void *dev_id)
|
|||
|
||||
if (i2c->state == STATE_READ)
|
||||
goto prepare_read;
|
||||
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
|
||||
case STATE_WRITE:
|
||||
if (bsr & SYNQUACER_I2C_BSR_LRB) {
|
||||
|
|
|
|||
|
|
@ -293,6 +293,8 @@ struct tegra_i2c_dev {
|
|||
bool is_curr_atomic_xfer;
|
||||
};
|
||||
|
||||
static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit);
|
||||
|
||||
static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
|
||||
unsigned long reg)
|
||||
{
|
||||
|
|
@ -419,7 +421,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
|
|||
dma_addr_t dma_phys;
|
||||
int err;
|
||||
|
||||
if (!i2c_dev->hw->has_apb_dma)
|
||||
if (!i2c_dev->hw->has_apb_dma || i2c_dev->is_vi)
|
||||
return 0;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_TEGRA20_APB_DMA)) {
|
||||
|
|
@ -655,32 +657,47 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!i2c_dev->hw->has_single_clk_source) {
|
||||
ret = clk_enable(i2c_dev->fast_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(i2c_dev->dev,
|
||||
"Enabling fast clk failed, err %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = clk_enable(i2c_dev->fast_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(i2c_dev->dev,
|
||||
"Enabling fast clk failed, err %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (i2c_dev->slow_clk) {
|
||||
ret = clk_enable(i2c_dev->slow_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to enable slow clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = clk_enable(i2c_dev->slow_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to enable slow clock: %d\n", ret);
|
||||
goto disable_fast_clk;
|
||||
}
|
||||
|
||||
ret = clk_enable(i2c_dev->div_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(i2c_dev->dev,
|
||||
"Enabling div clk failed, err %d\n", ret);
|
||||
clk_disable(i2c_dev->fast_clk);
|
||||
return ret;
|
||||
goto disable_slow_clk;
|
||||
}
|
||||
|
||||
/*
|
||||
* VI I2C device is attached to VE power domain which goes through
|
||||
* power ON/OFF during PM runtime resume/suspend. So, controller
|
||||
* should go through reset and need to re-initialize after power
|
||||
* domain ON.
|
||||
*/
|
||||
if (i2c_dev->is_vi) {
|
||||
ret = tegra_i2c_init(i2c_dev, true);
|
||||
if (ret)
|
||||
goto disable_div_clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
disable_div_clk:
|
||||
clk_disable(i2c_dev->div_clk);
|
||||
disable_slow_clk:
|
||||
clk_disable(i2c_dev->slow_clk);
|
||||
disable_fast_clk:
|
||||
clk_disable(i2c_dev->fast_clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
|
||||
|
|
@ -688,12 +705,8 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
|
|||
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable(i2c_dev->div_clk);
|
||||
|
||||
if (i2c_dev->slow_clk)
|
||||
clk_disable(i2c_dev->slow_clk);
|
||||
|
||||
if (!i2c_dev->hw->has_single_clk_source)
|
||||
clk_disable(i2c_dev->fast_clk);
|
||||
clk_disable(i2c_dev->slow_clk);
|
||||
clk_disable(i2c_dev->fast_clk);
|
||||
|
||||
return pinctrl_pm_select_idle_state(i2c_dev->dev);
|
||||
}
|
||||
|
|
@ -1716,20 +1729,16 @@ static int tegra_i2c_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, i2c_dev);
|
||||
|
||||
if (!i2c_dev->hw->has_single_clk_source) {
|
||||
ret = clk_prepare(i2c_dev->fast_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(i2c_dev->dev, "Clock prepare failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = clk_prepare(i2c_dev->fast_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(i2c_dev->dev, "Clock prepare failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (i2c_dev->slow_clk) {
|
||||
ret = clk_prepare(i2c_dev->slow_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to prepare slow clock: %d\n", ret);
|
||||
goto unprepare_fast_clk;
|
||||
}
|
||||
ret = clk_prepare(i2c_dev->slow_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to prepare slow clock: %d\n", ret);
|
||||
goto unprepare_fast_clk;
|
||||
}
|
||||
|
||||
if (i2c_dev->bus_clk_rate > I2C_MAX_FAST_MODE_FREQ &&
|
||||
|
|
@ -1750,7 +1759,15 @@ static int tegra_i2c_probe(struct platform_device *pdev)
|
|||
goto unprepare_slow_clk;
|
||||
}
|
||||
|
||||
pm_runtime_irq_safe(&pdev->dev);
|
||||
/*
|
||||
* VI I2C is in VE power domain which is not always on and not
|
||||
* an IRQ safe. So, IRQ safe device can't be attached to a non-IRQ
|
||||
* safe domain as it prevents powering off the PM domain.
|
||||
* Also, VI I2C device don't need to use runtime IRQ safe as it will
|
||||
* not be used for atomic transfers.
|
||||
*/
|
||||
if (!i2c_dev->is_vi)
|
||||
pm_runtime_irq_safe(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
if (!pm_runtime_enabled(&pdev->dev)) {
|
||||
ret = tegra_i2c_runtime_resume(&pdev->dev);
|
||||
|
|
@ -1835,12 +1852,10 @@ static int tegra_i2c_probe(struct platform_device *pdev)
|
|||
clk_unprepare(i2c_dev->div_clk);
|
||||
|
||||
unprepare_slow_clk:
|
||||
if (i2c_dev->is_vi)
|
||||
clk_unprepare(i2c_dev->slow_clk);
|
||||
clk_unprepare(i2c_dev->slow_clk);
|
||||
|
||||
unprepare_fast_clk:
|
||||
if (!i2c_dev->hw->has_single_clk_source)
|
||||
clk_unprepare(i2c_dev->fast_clk);
|
||||
clk_unprepare(i2c_dev->fast_clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1859,12 +1874,8 @@ static int tegra_i2c_remove(struct platform_device *pdev)
|
|||
tegra_i2c_runtime_suspend(&pdev->dev);
|
||||
|
||||
clk_unprepare(i2c_dev->div_clk);
|
||||
|
||||
if (i2c_dev->slow_clk)
|
||||
clk_unprepare(i2c_dev->slow_clk);
|
||||
|
||||
if (!i2c_dev->hw->has_single_clk_source)
|
||||
clk_unprepare(i2c_dev->fast_clk);
|
||||
clk_unprepare(i2c_dev->slow_clk);
|
||||
clk_unprepare(i2c_dev->fast_clk);
|
||||
|
||||
tegra_i2c_release_dma(i2c_dev);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
|
|||
goto exit_unsupported;
|
||||
if (read_write == I2C_SMBUS_READ)
|
||||
outb_p(data->block[0], SMBHSTDAT0);
|
||||
/* Fall through */
|
||||
fallthrough;
|
||||
case I2C_SMBUS_BLOCK_DATA:
|
||||
outb_p(command, SMBHSTCMD);
|
||||
if (read_write == I2C_SMBUS_WRITE) {
|
||||
|
|
@ -489,9 +489,9 @@ static void __exit i2c_vt596_exit(void)
|
|||
}
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, "
|
||||
"Mark D. Studebaker <mdsxyz123@yahoo.com> and "
|
||||
"Jean Delvare <jdelvare@suse.de>");
|
||||
MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>");
|
||||
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
|
||||
MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
|
||||
MODULE_DESCRIPTION("vt82c596 SMBus driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
|
|||
|
||||
case state_repeat_start:
|
||||
outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
|
||||
/* fallthrough */
|
||||
fallthrough;
|
||||
|
||||
case state_quick:
|
||||
if (iface->address_byte & 1) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pm_wakeirq.h>
|
||||
|
|
@ -181,6 +182,8 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
|
|||
|
||||
if (bri->prepare_recovery)
|
||||
bri->prepare_recovery(adap);
|
||||
if (bri->pinctrl)
|
||||
pinctrl_select_state(bri->pinctrl, bri->pins_gpio);
|
||||
|
||||
/*
|
||||
* If we can set SDA, we will always create a STOP to ensure additional
|
||||
|
|
@ -236,6 +239,8 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
|
|||
|
||||
if (bri->unprepare_recovery)
|
||||
bri->unprepare_recovery(adap);
|
||||
if (bri->pinctrl)
|
||||
pinctrl_select_state(bri->pinctrl, bri->pins_default);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -251,13 +256,135 @@ int i2c_recover_bus(struct i2c_adapter *adap)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_recover_bus);
|
||||
|
||||
static void i2c_init_recovery(struct i2c_adapter *adap)
|
||||
static void i2c_gpio_init_pinctrl_recovery(struct i2c_adapter *adap)
|
||||
{
|
||||
struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
|
||||
struct device *dev = &adap->dev;
|
||||
struct pinctrl *p = bri->pinctrl;
|
||||
|
||||
/*
|
||||
* we can't change states without pinctrl, so remove the states if
|
||||
* populated
|
||||
*/
|
||||
if (!p) {
|
||||
bri->pins_default = NULL;
|
||||
bri->pins_gpio = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bri->pins_default) {
|
||||
bri->pins_default = pinctrl_lookup_state(p,
|
||||
PINCTRL_STATE_DEFAULT);
|
||||
if (IS_ERR(bri->pins_default)) {
|
||||
dev_dbg(dev, PINCTRL_STATE_DEFAULT " state not found for GPIO recovery\n");
|
||||
bri->pins_default = NULL;
|
||||
}
|
||||
}
|
||||
if (!bri->pins_gpio) {
|
||||
bri->pins_gpio = pinctrl_lookup_state(p, "gpio");
|
||||
if (IS_ERR(bri->pins_gpio))
|
||||
bri->pins_gpio = pinctrl_lookup_state(p, "recovery");
|
||||
|
||||
if (IS_ERR(bri->pins_gpio)) {
|
||||
dev_dbg(dev, "no gpio or recovery state found for GPIO recovery\n");
|
||||
bri->pins_gpio = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* for pinctrl state changes, we need all the information */
|
||||
if (bri->pins_default && bri->pins_gpio) {
|
||||
dev_info(dev, "using pinctrl states for GPIO recovery");
|
||||
} else {
|
||||
bri->pinctrl = NULL;
|
||||
bri->pins_default = NULL;
|
||||
bri->pins_gpio = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int i2c_gpio_init_generic_recovery(struct i2c_adapter *adap)
|
||||
{
|
||||
struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
|
||||
struct device *dev = &adap->dev;
|
||||
struct gpio_desc *gpiod;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* don't touch the recovery information if the driver is not using
|
||||
* generic SCL recovery
|
||||
*/
|
||||
if (bri->recover_bus && bri->recover_bus != i2c_generic_scl_recovery)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* pins might be taken as GPIO, so we should inform pinctrl about
|
||||
* this and move the state to GPIO
|
||||
*/
|
||||
if (bri->pinctrl)
|
||||
pinctrl_select_state(bri->pinctrl, bri->pins_gpio);
|
||||
|
||||
/*
|
||||
* if there is incomplete or no recovery information, see if generic
|
||||
* GPIO recovery is available
|
||||
*/
|
||||
if (!bri->scl_gpiod) {
|
||||
gpiod = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN);
|
||||
if (PTR_ERR(gpiod) == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto cleanup_pinctrl_state;
|
||||
}
|
||||
if (!IS_ERR(gpiod)) {
|
||||
bri->scl_gpiod = gpiod;
|
||||
bri->recover_bus = i2c_generic_scl_recovery;
|
||||
dev_info(dev, "using generic GPIOs for recovery\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* SDA GPIOD line is optional, so we care about DEFER only */
|
||||
if (!bri->sda_gpiod) {
|
||||
/*
|
||||
* We have SCL. Pull SCL low and wait a bit so that SDA glitches
|
||||
* have no effect.
|
||||
*/
|
||||
gpiod_direction_output(bri->scl_gpiod, 0);
|
||||
udelay(10);
|
||||
gpiod = devm_gpiod_get(dev, "sda", GPIOD_IN);
|
||||
|
||||
/* Wait a bit in case of a SDA glitch, and then release SCL. */
|
||||
udelay(10);
|
||||
gpiod_direction_output(bri->scl_gpiod, 1);
|
||||
|
||||
if (PTR_ERR(gpiod) == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto cleanup_pinctrl_state;
|
||||
}
|
||||
if (!IS_ERR(gpiod))
|
||||
bri->sda_gpiod = gpiod;
|
||||
}
|
||||
|
||||
cleanup_pinctrl_state:
|
||||
/* change the state of the pins back to their default state */
|
||||
if (bri->pinctrl)
|
||||
pinctrl_select_state(bri->pinctrl, bri->pins_default);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_gpio_init_recovery(struct i2c_adapter *adap)
|
||||
{
|
||||
i2c_gpio_init_pinctrl_recovery(adap);
|
||||
return i2c_gpio_init_generic_recovery(adap);
|
||||
}
|
||||
|
||||
static int i2c_init_recovery(struct i2c_adapter *adap)
|
||||
{
|
||||
struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
|
||||
char *err_str;
|
||||
|
||||
if (!bri)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (i2c_gpio_init_recovery(adap) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (!bri->recover_bus) {
|
||||
err_str = "no recover_bus() found";
|
||||
|
|
@ -273,10 +400,7 @@ static void i2c_init_recovery(struct i2c_adapter *adap)
|
|||
if (gpiod_get_direction(bri->sda_gpiod) == 0)
|
||||
bri->set_sda = set_sda_gpio_value;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (bri->recover_bus == i2c_generic_scl_recovery) {
|
||||
} else if (bri->recover_bus == i2c_generic_scl_recovery) {
|
||||
/* Generic SCL recovery */
|
||||
if (!bri->set_scl || !bri->get_scl) {
|
||||
err_str = "no {get|set}_scl() found";
|
||||
|
|
@ -288,10 +412,12 @@ static void i2c_init_recovery(struct i2c_adapter *adap)
|
|||
}
|
||||
}
|
||||
|
||||
return;
|
||||
return 0;
|
||||
err:
|
||||
dev_err(&adap->dev, "Not using recovery: %s\n", err_str);
|
||||
adap->bus_recovery_info = NULL;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client)
|
||||
|
|
@ -319,11 +445,9 @@ static int i2c_device_probe(struct device *dev)
|
|||
if (!client)
|
||||
return 0;
|
||||
|
||||
driver = to_i2c_driver(dev->driver);
|
||||
|
||||
client->irq = client->init_irq;
|
||||
|
||||
if (!client->irq && !driver->disable_i2c_core_irq_mapping) {
|
||||
if (!client->irq) {
|
||||
int irq = -ENOENT;
|
||||
|
||||
if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
|
||||
|
|
@ -349,6 +473,8 @@ static int i2c_device_probe(struct device *dev)
|
|||
client->irq = irq;
|
||||
}
|
||||
|
||||
driver = to_i2c_driver(dev->driver);
|
||||
|
||||
/*
|
||||
* An I2C ID table is not mandatory, if and only if, a suitable OF
|
||||
* or ACPI ID table is supplied for the probing device.
|
||||
|
|
@ -1227,7 +1353,7 @@ static int i2c_setup_host_notify_irq_domain(struct i2c_adapter *adap)
|
|||
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_HOST_NOTIFY))
|
||||
return 0;
|
||||
|
||||
domain = irq_domain_create_linear(adap->dev.fwnode,
|
||||
domain = irq_domain_create_linear(adap->dev.parent->fwnode,
|
||||
I2C_ADDR_7BITS_COUNT,
|
||||
&i2c_host_notify_irq_ops, adap);
|
||||
if (!domain)
|
||||
|
|
@ -1318,12 +1444,16 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
|
|||
if (res)
|
||||
goto out_reg;
|
||||
|
||||
dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
|
||||
|
||||
pm_runtime_no_callbacks(&adap->dev);
|
||||
pm_suspend_ignore_children(&adap->dev, true);
|
||||
pm_runtime_enable(&adap->dev);
|
||||
|
||||
res = i2c_init_recovery(adap);
|
||||
if (res == -EPROBE_DEFER)
|
||||
goto out_reg;
|
||||
|
||||
dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
|
||||
|
||||
#ifdef CONFIG_I2C_COMPAT
|
||||
res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,
|
||||
adap->dev.parent);
|
||||
|
|
@ -1332,8 +1462,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
|
|||
"Failed to create compatibility class link\n");
|
||||
#endif
|
||||
|
||||
i2c_init_recovery(adap);
|
||||
|
||||
/* create pre-declared device nodes */
|
||||
of_i2c_register_devices(adap);
|
||||
i2c_acpi_register_devices(adap);
|
||||
|
|
|
|||
|
|
@ -761,8 +761,8 @@ static void __exit i2c_dev_exit(void)
|
|||
unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
|
||||
"Simon G. Vogl <simon@tk.uni-linz.ac.at>");
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
|
||||
MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
|
||||
MODULE_DESCRIPTION("I2C /dev entries driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
|
|||
case I2C_SLAVE_READ_PROCESSED:
|
||||
/* The previous byte made it to the bus, get next one */
|
||||
eeprom->buffer_idx++;
|
||||
/* fallthrough */
|
||||
fallthrough;
|
||||
case I2C_SLAVE_READ_REQUESTED:
|
||||
spin_lock(&eeprom->buffer_lock);
|
||||
*val = eeprom->buffer[eeprom->buffer_idx & eeprom->address_mask];
|
||||
|
|
|
|||
|
|
@ -1728,7 +1728,7 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
|
|||
/* hardware completion status should be available by this time */
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"could'nt get reset done status from h/w, timeout!\n");
|
||||
"couldn't get reset done status from h/w, timeout!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -334,19 +334,14 @@ void hinic_devlink_unregister(struct hinic_devlink_priv *priv)
|
|||
static int chip_fault_show(struct devlink_fmsg *fmsg,
|
||||
struct hinic_fault_event *event)
|
||||
{
|
||||
char fault_level[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {
|
||||
"fatal", "reset", "flr", "general", "suggestion"};
|
||||
char level_str[FAULT_SHOW_STR_LEN + 1] = {0};
|
||||
u8 level;
|
||||
const char * const level_str[FAULT_LEVEL_MAX + 1] = {
|
||||
"fatal", "reset", "flr", "general", "suggestion", "Unknown"};
|
||||
u8 fault_level;
|
||||
int err;
|
||||
|
||||
level = event->event.chip.err_level;
|
||||
if (level < FAULT_LEVEL_MAX)
|
||||
strncpy(level_str, fault_level[level], strlen(fault_level[level]));
|
||||
else
|
||||
strncpy(level_str, "Unknown", strlen("Unknown"));
|
||||
|
||||
if (level == FAULT_LEVEL_SERIOUS_FLR) {
|
||||
fault_level = (event->event.chip.err_level < FAULT_LEVEL_MAX) ?
|
||||
event->event.chip.err_level : FAULT_LEVEL_MAX;
|
||||
if (fault_level == FAULT_LEVEL_SERIOUS_FLR) {
|
||||
err = devlink_fmsg_u32_pair_put(fmsg, "Function level err func_id",
|
||||
(u32)event->event.chip.func_id);
|
||||
if (err)
|
||||
|
|
@ -361,7 +356,7 @@ static int chip_fault_show(struct devlink_fmsg *fmsg,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_string_pair_put(fmsg, "err_level", level_str);
|
||||
err = devlink_fmsg_string_pair_put(fmsg, "err_level", level_str[fault_level]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -381,18 +376,15 @@ static int chip_fault_show(struct devlink_fmsg *fmsg,
|
|||
static int fault_report_show(struct devlink_fmsg *fmsg,
|
||||
struct hinic_fault_event *event)
|
||||
{
|
||||
char fault_type[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {
|
||||
const char * const type_str[FAULT_TYPE_MAX + 1] = {
|
||||
"chip", "ucode", "mem rd timeout", "mem wr timeout",
|
||||
"reg rd timeout", "reg wr timeout", "phy fault"};
|
||||
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
|
||||
"reg rd timeout", "reg wr timeout", "phy fault", "Unknown"};
|
||||
u8 fault_type;
|
||||
int err;
|
||||
|
||||
if (event->type < FAULT_TYPE_MAX)
|
||||
strncpy(type_str, fault_type[event->type], strlen(fault_type[event->type]));
|
||||
else
|
||||
strncpy(type_str, "Unknown", strlen("Unknown"));
|
||||
fault_type = (event->type < FAULT_TYPE_MAX) ? event->type : FAULT_TYPE_MAX;
|
||||
|
||||
err = devlink_fmsg_string_pair_put(fmsg, "Fault type", type_str);
|
||||
err = devlink_fmsg_string_pair_put(fmsg, "Fault type", type_str[fault_type]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
|||
|
|
@ -504,8 +504,6 @@ enum hinic_fault_type {
|
|||
FAULT_TYPE_MAX,
|
||||
};
|
||||
|
||||
#define FAULT_SHOW_STR_LEN 16
|
||||
|
||||
enum hinic_fault_err_level {
|
||||
FAULT_LEVEL_FATAL,
|
||||
FAULT_LEVEL_SERIOUS_RESET,
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
|
|||
|
||||
new->flags = flags;
|
||||
|
||||
new->q.info = devm_kzalloc(dev, sizeof(*new->q.info) * num_descs,
|
||||
new->q.info = devm_kcalloc(dev, num_descs, sizeof(*new->q.info),
|
||||
GFP_KERNEL);
|
||||
if (!new->q.info) {
|
||||
netdev_err(lif->netdev, "Cannot allocate queue info\n");
|
||||
|
|
@ -462,7 +462,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
|
|||
new->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
|
||||
}
|
||||
|
||||
new->cq.info = devm_kzalloc(dev, sizeof(*new->cq.info) * num_descs,
|
||||
new->cq.info = devm_kcalloc(dev, num_descs, sizeof(*new->cq.info),
|
||||
GFP_KERNEL);
|
||||
if (!new->cq.info) {
|
||||
netdev_err(lif->netdev, "Cannot allocate completion queue info\n");
|
||||
|
|
|
|||
|
|
@ -474,13 +474,24 @@ static int emac_clks_phase1_init(struct platform_device *pdev,
|
|||
|
||||
ret = clk_prepare_enable(adpt->clk[EMAC_CLK_CFG_AHB]);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto disable_clk_axi;
|
||||
|
||||
ret = clk_set_rate(adpt->clk[EMAC_CLK_HIGH_SPEED], 19200000);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto disable_clk_cfg_ahb;
|
||||
|
||||
return clk_prepare_enable(adpt->clk[EMAC_CLK_HIGH_SPEED]);
|
||||
ret = clk_prepare_enable(adpt->clk[EMAC_CLK_HIGH_SPEED]);
|
||||
if (ret)
|
||||
goto disable_clk_cfg_ahb;
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk_cfg_ahb:
|
||||
clk_disable_unprepare(adpt->clk[EMAC_CLK_CFG_AHB]);
|
||||
disable_clk_axi:
|
||||
clk_disable_unprepare(adpt->clk[EMAC_CLK_AXI]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable clocks; needs emac_clks_phase1_init to be called before */
|
||||
|
|
|
|||
|
|
@ -979,7 +979,8 @@ static int ef100_process_design_param(struct efx_nic *efx,
|
|||
* EFX_MIN_DMAQ_SIZE is divisible by GRANULARITY.
|
||||
* This is very unlikely to fail.
|
||||
*/
|
||||
if (EFX_MIN_DMAQ_SIZE % reader->value) {
|
||||
if (!reader->value || reader->value > EFX_MIN_DMAQ_SIZE ||
|
||||
EFX_MIN_DMAQ_SIZE % (u32)reader->value) {
|
||||
netif_err(efx, probe, efx->net_dev,
|
||||
"%s size granularity is %llu, can't guarantee safety\n",
|
||||
reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
|
||||
|
|
|
|||
|
|
@ -351,6 +351,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
|
|||
plat_dat->has_gmac = true;
|
||||
plat_dat->bsp_priv = gmac;
|
||||
plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
|
||||
plat_dat->multicast_filter_bins = 0;
|
||||
|
||||
err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -164,6 +164,9 @@ static void dwmac1000_set_filter(struct mac_device_info *hw,
|
|||
value = GMAC_FRAME_FILTER_PR | GMAC_FRAME_FILTER_PCF;
|
||||
} else if (dev->flags & IFF_ALLMULTI) {
|
||||
value = GMAC_FRAME_FILTER_PM; /* pass all multi */
|
||||
} else if (!netdev_mc_empty(dev) && (mcbitslog2 == 0)) {
|
||||
/* Fall back to all multicast if we've no filter */
|
||||
value = GMAC_FRAME_FILTER_PM;
|
||||
} else if (!netdev_mc_empty(dev)) {
|
||||
struct netdev_hw_addr *ha;
|
||||
|
||||
|
|
|
|||
|
|
@ -208,13 +208,6 @@ static int mv3310_hwmon_config(struct phy_device *phydev, bool enable)
|
|||
MV_V2_TEMP_CTRL_MASK, val);
|
||||
}
|
||||
|
||||
static void mv3310_hwmon_disable(void *data)
|
||||
{
|
||||
struct phy_device *phydev = data;
|
||||
|
||||
mv3310_hwmon_config(phydev, false);
|
||||
}
|
||||
|
||||
static int mv3310_hwmon_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
|
|
@ -238,10 +231,6 @@ static int mv3310_hwmon_probe(struct phy_device *phydev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->hwmon_dev = devm_hwmon_device_register_with_info(dev,
|
||||
priv->hwmon_name, phydev,
|
||||
&mv3310_hwmon_chip_info, NULL);
|
||||
|
|
@ -426,6 +415,11 @@ static int mv3310_probe(struct phy_device *phydev)
|
|||
return phy_sfp_probe(phydev, &mv3310_sfp_ops);
|
||||
}
|
||||
|
||||
static void mv3310_remove(struct phy_device *phydev)
|
||||
{
|
||||
mv3310_hwmon_config(phydev, false);
|
||||
}
|
||||
|
||||
static int mv3310_suspend(struct phy_device *phydev)
|
||||
{
|
||||
return mv3310_power_down(phydev);
|
||||
|
|
@ -784,6 +778,7 @@ static struct phy_driver mv3310_drivers[] = {
|
|||
.read_status = mv3310_read_status,
|
||||
.get_tunable = mv3310_get_tunable,
|
||||
.set_tunable = mv3310_set_tunable,
|
||||
.remove = mv3310_remove,
|
||||
},
|
||||
{
|
||||
.phy_id = MARVELL_PHY_ID_88E2110,
|
||||
|
|
@ -798,6 +793,7 @@ static struct phy_driver mv3310_drivers[] = {
|
|||
.read_status = mv3310_read_status,
|
||||
.get_tunable = mv3310_get_tunable,
|
||||
.set_tunable = mv3310_set_tunable,
|
||||
.remove = mv3310_remove,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -615,7 +615,9 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
|
|||
if (c45_ids)
|
||||
dev->c45_ids = *c45_ids;
|
||||
dev->irq = bus->irq[addr];
|
||||
|
||||
dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr);
|
||||
device_initialize(&mdiodev->dev);
|
||||
|
||||
dev->state = PHY_DOWN;
|
||||
|
||||
|
|
@ -649,10 +651,8 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
|
|||
ret = phy_request_driver_module(dev, phy_id);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
device_initialize(&mdiodev->dev);
|
||||
} else {
|
||||
kfree(dev);
|
||||
if (ret) {
|
||||
put_device(&mdiodev->dev);
|
||||
dev = ERR_PTR(ret);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1504,7 +1504,7 @@ static int determine_ethernet_addr(struct r8152 *tp, struct sockaddr *sa)
|
|||
|
||||
sa->sa_family = dev->type;
|
||||
|
||||
ret = eth_platform_get_mac_address(&dev->dev, sa->sa_data);
|
||||
ret = eth_platform_get_mac_address(&tp->udev->dev, sa->sa_data);
|
||||
if (ret < 0) {
|
||||
if (tp->version == RTL_VER_01) {
|
||||
ret = pla_ocp_read(tp, PLA_IDR, 8, sa->sa_data);
|
||||
|
|
|
|||
|
|
@ -886,7 +886,8 @@ vmxnet3_parse_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
|
|||
|
||||
switch (protocol) {
|
||||
case IPPROTO_TCP:
|
||||
ctx->l4_hdr_size = tcp_hdrlen(skb);
|
||||
ctx->l4_hdr_size = skb->encapsulation ? inner_tcp_hdrlen(skb) :
|
||||
tcp_hdrlen(skb);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
ctx->l4_hdr_size = sizeof(struct udphdr);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,12 @@ static netdev_tx_t lapbeth_xmit(struct sk_buff *skb,
|
|||
if (!netif_running(dev))
|
||||
goto drop;
|
||||
|
||||
/* There should be a pseudo header of 1 byte added by upper layers.
|
||||
* Check to make sure it is there before reading it.
|
||||
*/
|
||||
if (skb->len < 1)
|
||||
goto drop;
|
||||
|
||||
switch (skb->data[0]) {
|
||||
case X25_IFACE_DATA:
|
||||
break;
|
||||
|
|
@ -305,6 +311,7 @@ static void lapbeth_setup(struct net_device *dev)
|
|||
dev->netdev_ops = &lapbeth_netdev_ops;
|
||||
dev->needs_free_netdev = true;
|
||||
dev->type = ARPHRD_X25;
|
||||
dev->hard_header_len = 0;
|
||||
dev->mtu = 1000;
|
||||
dev->addr_len = 0;
|
||||
}
|
||||
|
|
@ -331,7 +338,8 @@ static int lapbeth_new_device(struct net_device *dev)
|
|||
* then this driver prepends a length field of 2 bytes,
|
||||
* then the underlying Ethernet device prepends its own header.
|
||||
*/
|
||||
ndev->hard_header_len = -1 + 3 + 2 + dev->hard_header_len;
|
||||
ndev->needed_headroom = -1 + 3 + 2 + dev->hard_header_len
|
||||
+ dev->needed_headroom;
|
||||
|
||||
lapbeth = netdev_priv(ndev);
|
||||
lapbeth->axdev = ndev;
|
||||
|
|
|
|||
|
|
@ -307,6 +307,14 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb,
|
|||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
/* There should be a pseudo header of 1 byte added by upper layers.
|
||||
* Check to make sure it is there before reading it.
|
||||
*/
|
||||
if (skb->len < 1) {
|
||||
kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
switch (skb->data[0]) {
|
||||
case X25_IFACE_DATA:
|
||||
break;
|
||||
|
|
@ -752,6 +760,12 @@ static void x25_asy_setup(struct net_device *dev)
|
|||
dev->type = ARPHRD_X25;
|
||||
dev->tx_queue_len = 10;
|
||||
|
||||
/* When transmitting data:
|
||||
* first this driver removes a pseudo header of 1 byte,
|
||||
* then the lapb module prepends an LAPB header of at most 3 bytes.
|
||||
*/
|
||||
dev->needed_headroom = 3 - 1;
|
||||
|
||||
/* New-style flags. */
|
||||
dev->flags = IFF_NOARP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -818,7 +818,7 @@ static int pkey_keyblob2pkey2(const struct pkey_apqn *apqns, size_t nr_apqns,
|
|||
static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags,
|
||||
struct pkey_apqn *apqns, size_t *nr_apqns)
|
||||
{
|
||||
int rc = EINVAL;
|
||||
int rc;
|
||||
u32 _nr_apqns, *_apqns = NULL;
|
||||
struct keytoken_header *hdr = (struct keytoken_header *)key;
|
||||
|
||||
|
|
@ -886,7 +886,7 @@ static int pkey_apqns4keytype(enum pkey_key_type ktype,
|
|||
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
|
||||
struct pkey_apqn *apqns, size_t *nr_apqns)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
int rc;
|
||||
u32 _nr_apqns, *_apqns = NULL;
|
||||
|
||||
if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) {
|
||||
|
|
|
|||
|
|
@ -2303,7 +2303,7 @@ struct btrfs_backref_iter *btrfs_backref_iter_alloc(
|
|||
return NULL;
|
||||
|
||||
ret->path = btrfs_alloc_path();
|
||||
if (!ret) {
|
||||
if (!ret->path) {
|
||||
kfree(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ struct io_failure_record;
|
|||
*/
|
||||
#define CHUNK_ALLOCATED EXTENT_DIRTY
|
||||
#define CHUNK_TRIMMED EXTENT_DEFRAG
|
||||
#define CHUNK_STATE_MASK (CHUNK_ALLOCATED | \
|
||||
CHUNK_TRIMMED)
|
||||
|
||||
enum {
|
||||
IO_TREE_FS_PINNED_EXTENTS,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "delalloc-space.h"
|
||||
#include "block-group.h"
|
||||
#include "discard.h"
|
||||
#include "rcu-string.h"
|
||||
|
||||
#undef SCRAMBLE_DELAYED_REFS
|
||||
|
||||
|
|
@ -5668,6 +5669,19 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
|
|||
&start, &end,
|
||||
CHUNK_TRIMMED | CHUNK_ALLOCATED);
|
||||
|
||||
/* Check if there are any CHUNK_* bits left */
|
||||
if (start > device->total_bytes) {
|
||||
WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
|
||||
btrfs_warn_in_rcu(fs_info,
|
||||
"ignoring attempt to trim beyond device size: offset %llu length %llu device %s device size %llu",
|
||||
start, end - start + 1,
|
||||
rcu_str_deref(device->name),
|
||||
device->total_bytes);
|
||||
mutex_unlock(&fs_info->chunk_mutex);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ensure we skip the reserved area in the first 1M */
|
||||
start = max_t(u64, start, SZ_1M);
|
||||
|
||||
|
|
|
|||
|
|
@ -2282,7 +2282,7 @@ static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl,
|
|||
static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
|
||||
struct btrfs_free_space *info, bool update_stat)
|
||||
{
|
||||
struct btrfs_free_space *left_info;
|
||||
struct btrfs_free_space *left_info = NULL;
|
||||
struct btrfs_free_space *right_info;
|
||||
bool merged = false;
|
||||
u64 offset = info->offset;
|
||||
|
|
@ -2298,7 +2298,7 @@ static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
|
|||
if (right_info && rb_prev(&right_info->offset_index))
|
||||
left_info = rb_entry(rb_prev(&right_info->offset_index),
|
||||
struct btrfs_free_space, offset_index);
|
||||
else
|
||||
else if (!right_info)
|
||||
left_info = tree_search_offset(ctl, offset - 1, 0, 0);
|
||||
|
||||
/* See try_merge_free_space() comment. */
|
||||
|
|
|
|||
|
|
@ -654,12 +654,18 @@ static noinline int compress_file_range(struct async_chunk *async_chunk)
|
|||
page_error_op |
|
||||
PAGE_END_WRITEBACK);
|
||||
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
WARN_ON(pages[i]->mapping);
|
||||
put_page(pages[i]);
|
||||
/*
|
||||
* Ensure we only free the compressed pages if we have
|
||||
* them allocated, as we can still reach here with
|
||||
* inode_need_compress() == false.
|
||||
*/
|
||||
if (pages) {
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
WARN_ON(pages[i]->mapping);
|
||||
put_page(pages[i]);
|
||||
}
|
||||
kfree(pages);
|
||||
}
|
||||
kfree(pages);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -6622,7 +6628,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
|
|||
extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
|
||||
/* Only regular file could have regular/prealloc extent */
|
||||
if (!S_ISREG(inode->vfs_inode.i_mode)) {
|
||||
ret = -EUCLEAN;
|
||||
err = -EUCLEAN;
|
||||
btrfs_crit(fs_info,
|
||||
"regular/prealloc extent found for non-regular inode %llu",
|
||||
btrfs_ino(inode));
|
||||
|
|
|
|||
|
|
@ -517,6 +517,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
|||
char *compress_type;
|
||||
bool compress_force = false;
|
||||
enum btrfs_compression_type saved_compress_type;
|
||||
int saved_compress_level;
|
||||
bool saved_compress_force;
|
||||
int no_compress = 0;
|
||||
|
||||
|
|
@ -598,6 +599,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
|||
info->compress_type : BTRFS_COMPRESS_NONE;
|
||||
saved_compress_force =
|
||||
btrfs_test_opt(info, FORCE_COMPRESS);
|
||||
saved_compress_level = info->compress_level;
|
||||
if (token == Opt_compress ||
|
||||
token == Opt_compress_force ||
|
||||
strncmp(args[0].from, "zlib", 4) == 0) {
|
||||
|
|
@ -642,6 +644,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
|||
no_compress = 0;
|
||||
} else if (strncmp(args[0].from, "no", 2) == 0) {
|
||||
compress_type = "no";
|
||||
info->compress_level = 0;
|
||||
info->compress_type = 0;
|
||||
btrfs_clear_opt(info->mount_opt, COMPRESS);
|
||||
btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
|
||||
compress_force = false;
|
||||
|
|
@ -662,11 +666,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
|
|||
*/
|
||||
btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
|
||||
}
|
||||
if ((btrfs_test_opt(info, COMPRESS) &&
|
||||
(info->compress_type != saved_compress_type ||
|
||||
compress_force != saved_compress_force)) ||
|
||||
(!btrfs_test_opt(info, COMPRESS) &&
|
||||
no_compress == 1)) {
|
||||
if (no_compress == 1) {
|
||||
btrfs_info(info, "use no compression");
|
||||
} else if ((info->compress_type != saved_compress_type) ||
|
||||
(compress_force != saved_compress_force) ||
|
||||
(info->compress_level != saved_compress_level)) {
|
||||
btrfs_info(info, "%s %s compression, level %d",
|
||||
(compress_force) ? "force" : "use",
|
||||
compress_type, info->compress_level);
|
||||
|
|
@ -1382,6 +1386,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
|
|||
{
|
||||
struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb);
|
||||
const char *compress_type;
|
||||
const char *subvol_name;
|
||||
|
||||
if (btrfs_test_opt(info, DEGRADED))
|
||||
seq_puts(seq, ",degraded");
|
||||
|
|
@ -1468,8 +1473,13 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
|
|||
seq_puts(seq, ",ref_verify");
|
||||
seq_printf(seq, ",subvolid=%llu",
|
||||
BTRFS_I(d_inode(dentry))->root->root_key.objectid);
|
||||
seq_puts(seq, ",subvol=");
|
||||
seq_dentry(seq, dentry, " \t\n\\");
|
||||
subvol_name = btrfs_get_subvol_name_from_objectid(info,
|
||||
BTRFS_I(d_inode(dentry))->root->root_key.objectid);
|
||||
if (!IS_ERR(subvol_name)) {
|
||||
seq_puts(seq, ",subvol=");
|
||||
seq_escape(seq, subvol_name, " \t\n\\");
|
||||
kfree(subvol_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1950,6 +1960,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
|
|||
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
|
||||
}
|
||||
out:
|
||||
/*
|
||||
* We need to set SB_I_VERSION here otherwise it'll get cleared by VFS,
|
||||
* since the absence of the flag means it can be toggled off by remount.
|
||||
*/
|
||||
*flags |= SB_I_VERSION;
|
||||
|
||||
wake_up_process(fs_info->transaction_kthread);
|
||||
btrfs_remount_cleanup(fs_info, old_opts);
|
||||
clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
|
||||
|
|
|
|||
|
|
@ -1565,9 +1565,11 @@ void btrfs_sysfs_del_qgroups(struct btrfs_fs_info *fs_info)
|
|||
rbtree_postorder_for_each_entry_safe(qgroup, next,
|
||||
&fs_info->qgroup_tree, node)
|
||||
btrfs_sysfs_del_one_qgroup(fs_info, qgroup);
|
||||
kobject_del(fs_info->qgroups_kobj);
|
||||
kobject_put(fs_info->qgroups_kobj);
|
||||
fs_info->qgroups_kobj = NULL;
|
||||
if (fs_info->qgroups_kobj) {
|
||||
kobject_del(fs_info->qgroups_kobj);
|
||||
kobject_put(fs_info->qgroups_kobj);
|
||||
fs_info->qgroups_kobj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when qgroups get initialized, thus there is no need for locking */
|
||||
|
|
|
|||
|
|
@ -4036,11 +4036,8 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
|
|||
fs_info->csum_root,
|
||||
ds + cs, ds + cs + cl - 1,
|
||||
&ordered_sums, 0);
|
||||
if (ret) {
|
||||
btrfs_release_path(dst_path);
|
||||
kfree(ins_data);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4053,7 +4050,6 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
|
|||
* we have to do this after the loop above to avoid changing the
|
||||
* log tree while trying to change the log tree.
|
||||
*/
|
||||
ret = 0;
|
||||
while (!list_empty(&ordered_sums)) {
|
||||
struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next,
|
||||
struct btrfs_ordered_sum,
|
||||
|
|
|
|||
|
|
@ -4720,6 +4720,10 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
|
|||
}
|
||||
|
||||
mutex_lock(&fs_info->chunk_mutex);
|
||||
/* Clear all state bits beyond the shrunk device size */
|
||||
clear_extent_bits(&device->alloc_state, new_size, (u64)-1,
|
||||
CHUNK_STATE_MASK);
|
||||
|
||||
btrfs_device_set_disk_total_bytes(device, new_size);
|
||||
if (list_empty(&device->post_commit_list))
|
||||
list_add_tail(&device->post_commit_list,
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ int exfat_set_bitmap(struct inode *inode, unsigned int clu)
|
|||
b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx);
|
||||
|
||||
set_bit_le(b, sbi->vol_amap[i]->b_data);
|
||||
exfat_update_bh(sb, sbi->vol_amap[i], IS_DIRSYNC(inode));
|
||||
exfat_update_bh(sbi->vol_amap[i], IS_DIRSYNC(inode));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ void exfat_clear_bitmap(struct inode *inode, unsigned int clu)
|
|||
b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx);
|
||||
|
||||
clear_bit_le(b, sbi->vol_amap[i]->b_data);
|
||||
exfat_update_bh(sb, sbi->vol_amap[i], IS_DIRSYNC(inode));
|
||||
exfat_update_bh(sbi->vol_amap[i], IS_DIRSYNC(inode));
|
||||
|
||||
if (opts->discard) {
|
||||
int ret_discard;
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ int exfat_init_dir_entry(struct inode *inode, struct exfat_chain *p_dir,
|
|||
&ep->dentry.file.access_date,
|
||||
NULL);
|
||||
|
||||
exfat_update_bh(sb, bh, IS_DIRSYNC(inode));
|
||||
exfat_update_bh(bh, IS_DIRSYNC(inode));
|
||||
brelse(bh);
|
||||
|
||||
ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh, §or);
|
||||
|
|
@ -480,7 +480,7 @@ int exfat_init_dir_entry(struct inode *inode, struct exfat_chain *p_dir,
|
|||
exfat_init_stream_entry(ep,
|
||||
(type == TYPE_FILE) ? ALLOC_FAT_CHAIN : ALLOC_NO_FAT_CHAIN,
|
||||
start_clu, size);
|
||||
exfat_update_bh(sb, bh, IS_DIRSYNC(inode));
|
||||
exfat_update_bh(bh, IS_DIRSYNC(inode));
|
||||
brelse(bh);
|
||||
|
||||
return 0;
|
||||
|
|
@ -516,7 +516,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir,
|
|||
}
|
||||
|
||||
fep->dentry.file.checksum = cpu_to_le16(chksum);
|
||||
exfat_update_bh(sb, fbh, IS_DIRSYNC(inode));
|
||||
exfat_update_bh(fbh, IS_DIRSYNC(inode));
|
||||
release_fbh:
|
||||
brelse(fbh);
|
||||
return ret;
|
||||
|
|
@ -538,7 +538,7 @@ int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
|
|||
return -EIO;
|
||||
|
||||
ep->dentry.file.num_ext = (unsigned char)(num_entries - 1);
|
||||
exfat_update_bh(sb, bh, sync);
|
||||
exfat_update_bh(bh, sync);
|
||||
brelse(bh);
|
||||
|
||||
ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh, §or);
|
||||
|
|
@ -547,7 +547,7 @@ int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
|
|||
|
||||
ep->dentry.stream.name_len = p_uniname->name_len;
|
||||
ep->dentry.stream.name_hash = cpu_to_le16(p_uniname->name_hash);
|
||||
exfat_update_bh(sb, bh, sync);
|
||||
exfat_update_bh(bh, sync);
|
||||
brelse(bh);
|
||||
|
||||
for (i = EXFAT_FIRST_CLUSTER; i < num_entries; i++) {
|
||||
|
|
@ -556,7 +556,7 @@ int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
|
|||
return -EIO;
|
||||
|
||||
exfat_init_name_entry(ep, uniname);
|
||||
exfat_update_bh(sb, bh, sync);
|
||||
exfat_update_bh(bh, sync);
|
||||
brelse(bh);
|
||||
uniname += EXFAT_FILE_NAME_LEN;
|
||||
}
|
||||
|
|
@ -580,7 +580,7 @@ int exfat_remove_entries(struct inode *inode, struct exfat_chain *p_dir,
|
|||
return -EIO;
|
||||
|
||||
exfat_set_entry_type(ep, TYPE_DELETED);
|
||||
exfat_update_bh(sb, bh, IS_DIRSYNC(inode));
|
||||
exfat_update_bh(bh, IS_DIRSYNC(inode));
|
||||
brelse(bh);
|
||||
}
|
||||
|
||||
|
|
@ -604,16 +604,20 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es)
|
|||
es->modified = true;
|
||||
}
|
||||
|
||||
void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
|
||||
int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
|
||||
{
|
||||
int i;
|
||||
int i, err = 0;
|
||||
|
||||
for (i = 0; i < es->num_bh; i++) {
|
||||
if (es->modified)
|
||||
exfat_update_bh(es->sb, es->bh[i], sync);
|
||||
brelse(es->bh[i]);
|
||||
}
|
||||
if (es->modified)
|
||||
err = exfat_update_bhs(es->bh, es->num_bh, sync);
|
||||
|
||||
for (i = 0; i < es->num_bh; i++)
|
||||
if (err)
|
||||
bforget(es->bh[i]);
|
||||
else
|
||||
brelse(es->bh[i]);
|
||||
kfree(es);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int exfat_walk_fat_chain(struct super_block *sb,
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@
|
|||
#define EXFAT_SUPER_MAGIC 0x2011BAB0UL
|
||||
#define EXFAT_ROOT_INO 1
|
||||
|
||||
#define EXFAT_SB_DIRTY 0
|
||||
|
||||
#define EXFAT_CLUSTERS_UNTRACKED (~0u)
|
||||
|
||||
/*
|
||||
|
|
@ -226,7 +224,8 @@ struct exfat_sb_info {
|
|||
unsigned int num_FAT_sectors; /* num of FAT sectors */
|
||||
unsigned int root_dir; /* root dir cluster */
|
||||
unsigned int dentries_per_clu; /* num of dentries per cluster */
|
||||
unsigned int vol_flag; /* volume dirty flag */
|
||||
unsigned int vol_flags; /* volume flags */
|
||||
unsigned int vol_flags_persistent; /* volume flags to retain */
|
||||
struct buffer_head *boot_bh; /* buffer_head of BOOT sector */
|
||||
|
||||
unsigned int map_clu; /* allocation bitmap start cluster */
|
||||
|
|
@ -238,7 +237,6 @@ struct exfat_sb_info {
|
|||
unsigned int clu_srch_ptr; /* cluster search pointer */
|
||||
unsigned int used_clusters; /* number of used clusters */
|
||||
|
||||
unsigned long s_state;
|
||||
struct mutex s_lock; /* superblock lock */
|
||||
struct exfat_mount_options options;
|
||||
struct nls_table *nls_io; /* Charset used for input and display */
|
||||
|
|
@ -383,7 +381,8 @@ static inline int exfat_sector_to_cluster(struct exfat_sb_info *sbi,
|
|||
}
|
||||
|
||||
/* super.c */
|
||||
int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flag);
|
||||
int exfat_set_volume_dirty(struct super_block *sb);
|
||||
int exfat_clear_volume_dirty(struct super_block *sb);
|
||||
|
||||
/* fatent.c */
|
||||
#define exfat_get_next_cluster(sb, pclu) exfat_ent_get(sb, *(pclu), pclu)
|
||||
|
|
@ -463,7 +462,7 @@ struct exfat_dentry *exfat_get_dentry_cached(struct exfat_entry_set_cache *es,
|
|||
int num);
|
||||
struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
|
||||
struct exfat_chain *p_dir, int entry, unsigned int type);
|
||||
void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync);
|
||||
int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync);
|
||||
int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir);
|
||||
|
||||
/* inode.c */
|
||||
|
|
@ -515,7 +514,8 @@ void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
|
|||
u8 *tz, __le16 *time, __le16 *date, u8 *time_cs);
|
||||
u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type);
|
||||
u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type);
|
||||
void exfat_update_bh(struct super_block *sb, struct buffer_head *bh, int sync);
|
||||
void exfat_update_bh(struct buffer_head *bh, int sync);
|
||||
int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync);
|
||||
void exfat_chain_set(struct exfat_chain *ec, unsigned int dir,
|
||||
unsigned int size, unsigned char flags);
|
||||
void exfat_chain_dup(struct exfat_chain *dup, struct exfat_chain *ec);
|
||||
|
|
|
|||
|
|
@ -14,9 +14,8 @@
|
|||
|
||||
#define EXFAT_MAX_FILE_LEN 255
|
||||
|
||||
#define VOL_CLEAN 0x0000
|
||||
#define VOL_DIRTY 0x0002
|
||||
#define ERR_MEDIUM 0x0004
|
||||
#define VOLUME_DIRTY 0x0002
|
||||
#define MEDIA_FAILURE 0x0004
|
||||
|
||||
#define EXFAT_EOF_CLUSTER 0xFFFFFFFFu
|
||||
#define EXFAT_BAD_CLUSTER 0xFFFFFFF7u
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ int exfat_ent_set(struct super_block *sb, unsigned int loc,
|
|||
|
||||
fat_entry = (__le32 *)&(bh->b_data[off]);
|
||||
*fat_entry = cpu_to_le32(content);
|
||||
exfat_update_bh(sb, bh, sb->s_flags & SB_SYNCHRONOUS);
|
||||
exfat_update_bh(bh, sb->s_flags & SB_SYNCHRONOUS);
|
||||
exfat_mirror_bh(sb, sec, bh);
|
||||
brelse(bh);
|
||||
return 0;
|
||||
|
|
@ -174,7 +174,6 @@ int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
set_bit(EXFAT_SB_DIRTY, &sbi->s_state);
|
||||
clu = p_chain->dir;
|
||||
|
||||
if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
|
||||
|
|
@ -230,21 +229,6 @@ int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int exfat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
||||
for (i = 0; i < nr_bhs; i++)
|
||||
write_dirty_buffer(bhs[i], 0);
|
||||
|
||||
for (i = 0; i < nr_bhs; i++) {
|
||||
wait_on_buffer(bhs[i]);
|
||||
if (!err && !buffer_uptodate(bhs[i]))
|
||||
err = -EIO;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int exfat_zeroed_cluster(struct inode *dir, unsigned int clu)
|
||||
{
|
||||
struct super_block *sb = dir->i_sb;
|
||||
|
|
@ -266,41 +250,23 @@ int exfat_zeroed_cluster(struct inode *dir, unsigned int clu)
|
|||
}
|
||||
|
||||
/* Zeroing the unused blocks on this cluster */
|
||||
n = 0;
|
||||
while (blknr < last_blknr) {
|
||||
bhs[n] = sb_getblk(sb, blknr);
|
||||
if (!bhs[n]) {
|
||||
err = -ENOMEM;
|
||||
goto release_bhs;
|
||||
}
|
||||
memset(bhs[n]->b_data, 0, sb->s_blocksize);
|
||||
exfat_update_bh(sb, bhs[n], 0);
|
||||
|
||||
n++;
|
||||
blknr++;
|
||||
|
||||
if (n == nr_bhs) {
|
||||
if (IS_DIRSYNC(dir)) {
|
||||
err = exfat_sync_bhs(bhs, n);
|
||||
if (err)
|
||||
goto release_bhs;
|
||||
for (n = 0; n < nr_bhs && blknr < last_blknr; n++, blknr++) {
|
||||
bhs[n] = sb_getblk(sb, blknr);
|
||||
if (!bhs[n]) {
|
||||
err = -ENOMEM;
|
||||
goto release_bhs;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
brelse(bhs[i]);
|
||||
n = 0;
|
||||
memset(bhs[n]->b_data, 0, sb->s_blocksize);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_DIRSYNC(dir)) {
|
||||
err = exfat_sync_bhs(bhs, n);
|
||||
err = exfat_update_bhs(bhs, n, IS_DIRSYNC(dir));
|
||||
if (err)
|
||||
goto release_bhs;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
brelse(bhs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
brelse(bhs[i]);
|
||||
|
||||
return 0;
|
||||
|
||||
release_bhs:
|
||||
|
|
@ -358,8 +324,6 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
|
|||
}
|
||||
}
|
||||
|
||||
set_bit(EXFAT_SB_DIRTY, &sbi->s_state);
|
||||
|
||||
p_chain->dir = EXFAT_EOF_CLUSTER;
|
||||
|
||||
while ((new_clu = exfat_find_free_bitmap(sb, hint_clu)) !=
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user