forked from Minki/linux
Merge ra.kernel.org:/pub/scm/linux/kernel/git/davem/net
Two new tls tests added in parallel in both net and net-next. Used Stephen Rothwell's linux-next resolution. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
e366fa4350
@ -75,3 +75,12 @@ Contact: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Description:
|
||||
Amount (in KiB) of low (or normal) memory in the
|
||||
balloon.
|
||||
|
||||
What: /sys/devices/system/xen_memory/xen_memory0/scrub_pages
|
||||
Date: September 2018
|
||||
KernelVersion: 4.20
|
||||
Contact: xen-devel@lists.xenproject.org
|
||||
Description:
|
||||
Control scrubbing pages before returning them to Xen for others domains
|
||||
use. Can be set with xen_scrub_pages cmdline
|
||||
parameter. Default value controlled with CONFIG_XEN_SCRUB_PAGES_DEFAULT.
|
||||
|
@ -5000,6 +5000,12 @@
|
||||
Disables the PV optimizations forcing the HVM guest to
|
||||
run as generic HVM guest with no PV drivers.
|
||||
|
||||
xen_scrub_pages= [XEN]
|
||||
Boolean option to control scrubbing pages before giving them back
|
||||
to Xen, for use by other domains. Can be also changed at runtime
|
||||
with /sys/devices/system/xen_memory/xen_memory0/scrub_pages.
|
||||
Default value controlled with CONFIG_XEN_SCRUB_PAGES_DEFAULT.
|
||||
|
||||
xirc2ps_cs= [NET,PCMCIA]
|
||||
Format:
|
||||
<irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
|
||||
|
@ -348,3 +348,7 @@ Version History
|
||||
1.13.1 Fix deadlock caused by early md_stop_writes(). Also fix size an
|
||||
state races.
|
||||
1.13.2 Fix raid redundancy validation and avoid keeping raid set frozen
|
||||
1.14.0 Fix reshape race on small devices. Fix stripe adding reshape
|
||||
deadlock/potential data corruption. Update superblock when
|
||||
specific devices are requested via rebuild. Fix RAID leg
|
||||
rebuild errors.
|
||||
|
@ -10,6 +10,7 @@ Required properties:
|
||||
Use "cdns,pc302-gem" for Picochip picoXcell pc302 and later devices based on
|
||||
the Cadence GEM, or the generic form: "cdns,gem".
|
||||
Use "atmel,sama5d2-gem" for the GEM IP (10/100) available on Atmel sama5d2 SoCs.
|
||||
Use "atmel,sama5d3-macb" for the 10/100Mbit IP available on Atmel sama5d3 SoCs.
|
||||
Use "atmel,sama5d3-gem" for the Gigabit IP available on Atmel sama5d3 SoCs.
|
||||
Use "atmel,sama5d4-gem" for the GEM IP (10/100) available on Atmel sama5d4 SoCs.
|
||||
Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
|
||||
|
@ -848,7 +848,7 @@ struct file_operations
|
||||
----------------------
|
||||
|
||||
This describes how the VFS can manipulate an open file. As of kernel
|
||||
4.1, the following members are defined:
|
||||
4.18, the following members are defined:
|
||||
|
||||
struct file_operations {
|
||||
struct module *owner;
|
||||
@ -858,11 +858,11 @@ struct file_operations {
|
||||
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
|
||||
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
|
||||
int (*iterate) (struct file *, struct dir_context *);
|
||||
int (*iterate_shared) (struct file *, struct dir_context *);
|
||||
__poll_t (*poll) (struct file *, struct poll_table_struct *);
|
||||
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
|
||||
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
|
||||
int (*mmap) (struct file *, struct vm_area_struct *);
|
||||
int (*mremap)(struct file *, struct vm_area_struct *);
|
||||
int (*open) (struct inode *, struct file *);
|
||||
int (*flush) (struct file *, fl_owner_t id);
|
||||
int (*release) (struct inode *, struct file *);
|
||||
@ -882,6 +882,10 @@ struct file_operations {
|
||||
#ifndef CONFIG_MMU
|
||||
unsigned (*mmap_capabilities)(struct file *);
|
||||
#endif
|
||||
ssize_t (*copy_file_range)(struct file *, loff_t, struct file *, loff_t, size_t, unsigned int);
|
||||
int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t, u64);
|
||||
int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t, u64);
|
||||
int (*fadvise)(struct file *, loff_t, loff_t, int);
|
||||
};
|
||||
|
||||
Again, all methods are called without any locks being held, unless
|
||||
@ -899,6 +903,9 @@ otherwise noted.
|
||||
|
||||
iterate: called when the VFS needs to read the directory contents
|
||||
|
||||
iterate_shared: called when the VFS needs to read the directory contents
|
||||
when filesystem supports concurrent dir iterators
|
||||
|
||||
poll: called by the VFS when a process wants to check if there is
|
||||
activity on this file and (optionally) go to sleep until there
|
||||
is activity. Called by the select(2) and poll(2) system calls
|
||||
@ -951,6 +958,16 @@ otherwise noted.
|
||||
|
||||
fallocate: called by the VFS to preallocate blocks or punch a hole.
|
||||
|
||||
copy_file_range: called by the copy_file_range(2) system call.
|
||||
|
||||
clone_file_range: called by the ioctl(2) system call for FICLONERANGE and
|
||||
FICLONE commands.
|
||||
|
||||
dedupe_file_range: called by the ioctl(2) system call for FIDEDUPERANGE
|
||||
command.
|
||||
|
||||
fadvise: possibly called by the fadvise64() system call.
|
||||
|
||||
Note that the file operations are implemented by the specific
|
||||
filesystem in which the inode resides. When opening a device node
|
||||
(character or block special) most filesystems will call special
|
||||
|
81
Documentation/process/code-of-conduct.rst
Normal file
81
Documentation/process/code-of-conduct.rst
Normal file
@ -0,0 +1,81 @@
|
||||
Contributor Covenant Code of Conduct
|
||||
++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Our Pledge
|
||||
==========
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and
|
||||
expression, level of experience, education, socio-economic status, nationality,
|
||||
personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
Our Standards
|
||||
=============
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others’ private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
|
||||
Our Responsibilities
|
||||
====================
|
||||
|
||||
Maintainers are responsible for clarifying the standards of acceptable behavior
|
||||
and are expected to take appropriate and fair corrective action in response to
|
||||
any instances of unacceptable behavior.
|
||||
|
||||
Maintainers have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, or to ban temporarily or permanently any
|
||||
contributor for other behaviors that they deem inappropriate, threatening,
|
||||
offensive, or harmful.
|
||||
|
||||
Scope
|
||||
=====
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
Enforcement
|
||||
===========
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the Technical Advisory Board (TAB) at
|
||||
<tab@lists.linux-foundation.org>. All complaints will be reviewed and
|
||||
investigated and will result in a response that is deemed necessary and
|
||||
appropriate to the circumstances. The TAB is obligated to maintain
|
||||
confidentiality with regard to the reporter of an incident. Further details of
|
||||
specific enforcement policies may be posted separately.
|
||||
|
||||
Maintainers who do not follow or enforce the Code of Conduct in good faith may
|
||||
face temporary or permanent repercussions as determined by other members of the
|
||||
project’s leadership.
|
||||
|
||||
Attribution
|
||||
===========
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
@ -1,28 +0,0 @@
|
||||
Code of Conflict
|
||||
----------------
|
||||
|
||||
The Linux kernel development effort is a very personal process compared
|
||||
to "traditional" ways of developing software. Your code and ideas
|
||||
behind it will be carefully reviewed, often resulting in critique and
|
||||
criticism. The review will almost always require improvements to the
|
||||
code before it can be included in the kernel. Know that this happens
|
||||
because everyone involved wants to see the best possible solution for
|
||||
the overall success of Linux. This development process has been proven
|
||||
to create the most robust operating system kernel ever, and we do not
|
||||
want to do anything to cause the quality of submission and eventual
|
||||
result to ever decrease.
|
||||
|
||||
If however, anyone feels personally abused, threatened, or otherwise
|
||||
uncomfortable due to this process, that is not acceptable. If so,
|
||||
please contact the Linux Foundation's Technical Advisory Board at
|
||||
<tab@lists.linux-foundation.org>, or the individual members, and they
|
||||
will work to resolve the issue to the best of their ability. For more
|
||||
information on who is on the Technical Advisory Board and what their
|
||||
role is, please see:
|
||||
|
||||
- http://www.linuxfoundation.org/projects/linux/tab
|
||||
|
||||
As a reviewer of code, please strive to keep things civil and focused on
|
||||
the technical issues involved. We are all humans, and frustrations can
|
||||
be high on both sides of the process. Try to keep in mind the immortal
|
||||
words of Bill and Ted, "Be excellent to each other."
|
@ -20,7 +20,7 @@ Below are the essential guides that every developer should read.
|
||||
:maxdepth: 1
|
||||
|
||||
howto
|
||||
code-of-conflict
|
||||
code-of-conduct
|
||||
development-process
|
||||
submitting-patches
|
||||
coding-style
|
||||
|
@ -35,25 +35,25 @@ and two USB cables, connected like this:
|
||||
( If your system does not list a debug port capability then you probably
|
||||
won't be able to use the USB debug key. )
|
||||
|
||||
b.) You also need a Netchip USB debug cable/key:
|
||||
b.) You also need a NetChip USB debug cable/key:
|
||||
|
||||
http://www.plxtech.com/products/NET2000/NET20DC/default.asp
|
||||
|
||||
This is a small blue plastic connector with two USB connections,
|
||||
This is a small blue plastic connector with two USB connections;
|
||||
it draws power from its USB connections.
|
||||
|
||||
c.) You need a second client/console system with a high speed USB 2.0
|
||||
port.
|
||||
|
||||
d.) The Netchip device must be plugged directly into the physical
|
||||
d.) The NetChip device must be plugged directly into the physical
|
||||
debug port on the "host/target" system. You cannot use a USB hub in
|
||||
between the physical debug port and the "host/target" system.
|
||||
|
||||
The EHCI debug controller is bound to a specific physical USB
|
||||
port and the Netchip device will only work as an early printk
|
||||
port and the NetChip device will only work as an early printk
|
||||
device in this port. The EHCI host controllers are electrically
|
||||
wired such that the EHCI debug controller is hooked up to the
|
||||
first physical and there is no way to change this via software.
|
||||
first physical port and there is no way to change this via software.
|
||||
You can find the physical port through experimentation by trying
|
||||
each physical port on the system and rebooting. Or you can try
|
||||
and use lsusb or look at the kernel info messages emitted by the
|
||||
@ -65,9 +65,9 @@ and two USB cables, connected like this:
|
||||
to the hardware vendor, because there is no reason not to wire
|
||||
this port into one of the physically accessible ports.
|
||||
|
||||
e.) It is also important to note, that many versions of the Netchip
|
||||
e.) It is also important to note, that many versions of the NetChip
|
||||
device require the "client/console" system to be plugged into the
|
||||
right and side of the device (with the product logo facing up and
|
||||
right hand side of the device (with the product logo facing up and
|
||||
readable left to right). The reason being is that the 5 volt
|
||||
power supply is taken from only one side of the device and it
|
||||
must be the side that does not get rebooted.
|
||||
@ -81,13 +81,18 @@ and two USB cables, connected like this:
|
||||
CONFIG_EARLY_PRINTK_DBGP=y
|
||||
|
||||
And you need to add the boot command line: "earlyprintk=dbgp".
|
||||
|
||||
(If you are using Grub, append it to the 'kernel' line in
|
||||
/etc/grub.conf)
|
||||
/etc/grub.conf. If you are using Grub2 on a BIOS firmware system,
|
||||
append it to the 'linux' line in /boot/grub2/grub.cfg. If you are
|
||||
using Grub2 on an EFI firmware system, append it to the 'linux'
|
||||
or 'linuxefi' line in /boot/grub2/grub.cfg or
|
||||
/boot/efi/EFI/<distro>/grub.cfg.)
|
||||
|
||||
On systems with more than one EHCI debug controller you must
|
||||
specify the correct EHCI debug controller number. The ordering
|
||||
comes from the PCI bus enumeration of the EHCI controllers. The
|
||||
default with no number argument is "0" the first EHCI debug
|
||||
default with no number argument is "0" or the first EHCI debug
|
||||
controller. To use the second EHCI debug controller, you would
|
||||
use the command line: "earlyprintk=dbgp1"
|
||||
|
||||
@ -111,7 +116,7 @@ and two USB cables, connected like this:
|
||||
see the raw output.
|
||||
|
||||
c.) On Nvidia Southbridge based systems: the kernel will try to probe
|
||||
and find out which port has debug device connected.
|
||||
and find out which port has a debug device connected.
|
||||
|
||||
3. Testing that it works fine:
|
||||
|
||||
|
26
MAINTAINERS
26
MAINTAINERS
@ -5625,6 +5625,8 @@ F: lib/fault-inject.c
|
||||
|
||||
FBTFT Framebuffer drivers
|
||||
M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/staging/fbtft/
|
||||
|
||||
@ -6060,7 +6062,7 @@ F: Documentation/gcc-plugins.txt
|
||||
|
||||
GASKET DRIVER FRAMEWORK
|
||||
M: Rob Springer <rspringer@google.com>
|
||||
M: John Joseph <jnjoseph@google.com>
|
||||
M: Todd Poynor <toddpoynor@google.com>
|
||||
M: Ben Chan <benchan@chromium.org>
|
||||
S: Maintained
|
||||
F: drivers/staging/gasket/
|
||||
@ -7016,6 +7018,20 @@ F: drivers/crypto/vmx/aes*
|
||||
F: drivers/crypto/vmx/ghash*
|
||||
F: drivers/crypto/vmx/ppc-xlate.pl
|
||||
|
||||
IBM Power PCI Hotplug Driver for RPA-compliant PPC64 platform
|
||||
M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Supported
|
||||
F: drivers/pci/hotplug/rpaphp*
|
||||
|
||||
IBM Power IO DLPAR Driver for RPA-compliant PPC64 platform
|
||||
M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Supported
|
||||
F: drivers/pci/hotplug/rpadlpar*
|
||||
|
||||
IBM ServeRAID RAID DRIVER
|
||||
S: Orphan
|
||||
F: drivers/scsi/ips.*
|
||||
@ -8309,7 +8325,7 @@ F: include/linux/libata.h
|
||||
F: Documentation/devicetree/bindings/ata/
|
||||
|
||||
LIBLOCKDEP
|
||||
M: Sasha Levin <alexander.levin@verizon.com>
|
||||
M: Sasha Levin <alexander.levin@microsoft.com>
|
||||
S: Maintained
|
||||
F: tools/lib/lockdep/
|
||||
|
||||
@ -11163,7 +11179,7 @@ F: drivers/pci/controller/dwc/pci-exynos.c
|
||||
|
||||
PCI DRIVER FOR SYNOPSYS DESIGNWARE
|
||||
M: Jingoo Han <jingoohan1@gmail.com>
|
||||
M: Joao Pinto <Joao.Pinto@synopsys.com>
|
||||
M: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/designware-pcie.txt
|
||||
@ -11355,10 +11371,10 @@ S: Maintained
|
||||
F: drivers/platform/x86/peaq-wmi.c
|
||||
|
||||
PER-CPU MEMORY ALLOCATOR
|
||||
M: Dennis Zhou <dennis@kernel.org>
|
||||
M: Tejun Heo <tj@kernel.org>
|
||||
M: Christoph Lameter <cl@linux.com>
|
||||
M: Dennis Zhou <dennisszhou@gmail.com>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git
|
||||
S: Maintained
|
||||
F: include/linux/percpu*.h
|
||||
F: mm/percpu*.c
|
||||
|
24
Makefile
24
Makefile
@ -2,7 +2,7 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc4
|
||||
NAME = Merciless Moray
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -299,19 +299,7 @@ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
|
||||
KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
|
||||
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
|
||||
|
||||
# SUBARCH tells the usermode build what the underlying arch is. That is set
|
||||
# first, and if a usermode build is happening, the "ARCH=um" on the command
|
||||
# line overrides the setting of ARCH below. If a native build is happening,
|
||||
# then ARCH is assigned, getting whatever value it gets normally, and
|
||||
# SUBARCH is subsequently ignored.
|
||||
|
||||
SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
|
||||
-e s/sun4u/sparc64/ \
|
||||
-e s/arm.*/arm/ -e s/sa110/arm/ \
|
||||
-e s/s390x/s390/ -e s/parisc64/parisc/ \
|
||||
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
|
||||
-e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
|
||||
-e s/riscv.*/riscv/)
|
||||
include scripts/subarch.include
|
||||
|
||||
# Cross compiling and selecting different set of gcc/bin-utils
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -616,6 +604,11 @@ CFLAGS_GCOV := -fprofile-arcs -ftest-coverage \
|
||||
$(call cc-disable-warning,maybe-uninitialized,)
|
||||
export CFLAGS_GCOV
|
||||
|
||||
# The arch Makefiles can override CC_FLAGS_FTRACE. We may also append it later.
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
CC_FLAGS_FTRACE := -pg
|
||||
endif
|
||||
|
||||
# The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default
|
||||
# values of the respective KBUILD_* variables
|
||||
ARCH_CPPFLAGS :=
|
||||
@ -755,9 +748,6 @@ KBUILD_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly) \
|
||||
endif
|
||||
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
ifndef CC_FLAGS_FTRACE
|
||||
CC_FLAGS_FTRACE := -pg
|
||||
endif
|
||||
ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
||||
# gcc 5 supports generating the mcount tables directly
|
||||
ifeq ($(call cc-option-yn,-mrecord-mcount),y)
|
||||
|
@ -41,7 +41,7 @@
|
||||
};
|
||||
|
||||
macb1: ethernet@f802c000 {
|
||||
compatible = "cdns,at91sam9260-macb", "cdns,macb";
|
||||
compatible = "atmel,sama5d3-macb", "cdns,at91sam9260-macb", "cdns,macb";
|
||||
reg = <0xf802c000 0x100>;
|
||||
interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>;
|
||||
pinctrl-names = "default";
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
|
||||
{
|
||||
asm goto("1: nop\n\t"
|
||||
asm_volatile_goto("1: nop\n\t"
|
||||
".pushsection __jump_table, \"aw\"\n\t"
|
||||
".align 3\n\t"
|
||||
".quad 1b, %l[l_yes], %c0\n\t"
|
||||
@ -42,7 +42,7 @@ l_yes:
|
||||
|
||||
static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
|
||||
{
|
||||
asm goto("1: b %l[l_yes]\n\t"
|
||||
asm_volatile_goto("1: b %l[l_yes]\n\t"
|
||||
".pushsection __jump_table, \"aw\"\n\t"
|
||||
".align 3\n\t"
|
||||
".quad 1b, %l[l_yes], %c0\n\t"
|
||||
|
@ -54,6 +54,7 @@ arm64-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o \
|
||||
arm64-obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
|
||||
arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
|
||||
arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
arm64-obj-$(CONFIG_CRASH_CORE) += crash_core.o
|
||||
arm64-obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
|
||||
arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o
|
||||
|
||||
|
19
arch/arm64/kernel/crash_core.c
Normal file
19
arch/arm64/kernel/crash_core.c
Normal file
@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) Linaro.
|
||||
* Copyright (C) Huawei Futurewei Technologies.
|
||||
*/
|
||||
|
||||
#include <linux/crash_core.h>
|
||||
#include <asm/memory.h>
|
||||
|
||||
void arch_crash_save_vmcoreinfo(void)
|
||||
{
|
||||
VMCOREINFO_NUMBER(VA_BITS);
|
||||
/* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
|
||||
vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
|
||||
kimage_voffset);
|
||||
vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n",
|
||||
PHYS_OFFSET);
|
||||
vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
|
||||
}
|
@ -358,14 +358,3 @@ void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_HIBERNATION */
|
||||
|
||||
void arch_crash_save_vmcoreinfo(void)
|
||||
{
|
||||
VMCOREINFO_NUMBER(VA_BITS);
|
||||
/* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
|
||||
vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
|
||||
kimage_voffset);
|
||||
vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n",
|
||||
PHYS_OFFSET);
|
||||
vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ static inline long ffz(int x)
|
||||
* This is defined the same way as ffs.
|
||||
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
|
||||
*/
|
||||
static inline long fls(int x)
|
||||
static inline int fls(int x)
|
||||
{
|
||||
int r;
|
||||
|
||||
@ -232,7 +232,7 @@ static inline long fls(int x)
|
||||
* the libc and compiler builtin ffs routines, therefore
|
||||
* differs in spirit from the above ffz (man ffs).
|
||||
*/
|
||||
static inline long ffs(int x)
|
||||
static inline int ffs(int x)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
@ -60,7 +60,7 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
|
||||
panic("Can't create %s() memory pool!", __func__);
|
||||
else
|
||||
gen_pool_add(coherent_pool,
|
||||
pfn_to_virt(max_low_pfn),
|
||||
(unsigned long)pfn_to_virt(max_low_pfn),
|
||||
hexagon_coherent_pool_size, -1);
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ static int cbc_paes_crypt(struct blkcipher_desc *desc, unsigned long modifier,
|
||||
walk->dst.virt.addr, walk->src.virt.addr, n);
|
||||
if (k)
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes - k);
|
||||
if (n < k) {
|
||||
if (k < n) {
|
||||
if (__cbc_paes_set_key(ctx) != 0)
|
||||
return blkcipher_walk_done(desc, walk, -EIO);
|
||||
memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
|
||||
|
@ -1272,4 +1272,8 @@ void intel_pmu_lbr_init_knl(void)
|
||||
|
||||
x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
|
||||
x86_pmu.lbr_sel_map = snb_lbr_sel_map;
|
||||
|
||||
/* Knights Landing does have MISPREDICT bit */
|
||||
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP)
|
||||
x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS;
|
||||
}
|
||||
|
@ -19,9 +19,6 @@ static inline void native_set_pte(pte_t *ptep , pte_t pte)
|
||||
|
||||
static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
|
||||
{
|
||||
#ifdef CONFIG_PAGE_TABLE_ISOLATION
|
||||
pmd.pud.p4d.pgd = pti_set_user_pgtbl(&pmdp->pud.p4d.pgd, pmd.pud.p4d.pgd);
|
||||
#endif
|
||||
*pmdp = pmd;
|
||||
}
|
||||
|
||||
@ -61,9 +58,6 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp)
|
||||
#ifdef CONFIG_SMP
|
||||
static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
|
||||
{
|
||||
#ifdef CONFIG_PAGE_TABLE_ISOLATION
|
||||
pti_set_user_pgtbl(&xp->pud.p4d.pgd, __pgd(0));
|
||||
#endif
|
||||
return __pmd(xchg((pmdval_t *)xp, 0));
|
||||
}
|
||||
#else
|
||||
@ -73,9 +67,6 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
|
||||
#ifdef CONFIG_SMP
|
||||
static inline pud_t native_pudp_get_and_clear(pud_t *xp)
|
||||
{
|
||||
#ifdef CONFIG_PAGE_TABLE_ISOLATION
|
||||
pti_set_user_pgtbl(&xp->p4d.pgd, __pgd(0));
|
||||
#endif
|
||||
return __pud(xchg((pudval_t *)xp, 0));
|
||||
}
|
||||
#else
|
||||
|
@ -1640,6 +1640,7 @@ static int do_open(struct inode *inode, struct file *filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static int proc_apm_show(struct seq_file *m, void *v)
|
||||
{
|
||||
unsigned short bx;
|
||||
@ -1719,6 +1720,7 @@ static int proc_apm_show(struct seq_file *m, void *v)
|
||||
units);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int apm(void *unused)
|
||||
{
|
||||
|
@ -7,11 +7,17 @@
|
||||
#include <linux/eisa.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
|
||||
static __init int eisa_bus_probe(void)
|
||||
{
|
||||
void __iomem *p = ioremap(0x0FFFD9, 4);
|
||||
void __iomem *p;
|
||||
|
||||
if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
|
||||
if (xen_pv_domain() && !xen_initial_domain())
|
||||
return 0;
|
||||
|
||||
p = ioremap(0x0FFFD9, 4);
|
||||
if (p && readl(p) == 'E' + ('I' << 8) + ('S' << 16) + ('A' << 24))
|
||||
EISA_bus = 1;
|
||||
iounmap(p);
|
||||
return 0;
|
||||
|
@ -111,8 +111,10 @@ int arch_register_cpu(int num)
|
||||
/*
|
||||
* Currently CPU0 is only hotpluggable on Intel platforms. Other
|
||||
* vendors can add hotplug support later.
|
||||
* Xen PV guests don't support CPU0 hotplug at all.
|
||||
*/
|
||||
if (c->x86_vendor != X86_VENDOR_INTEL)
|
||||
if (c->x86_vendor != X86_VENDOR_INTEL ||
|
||||
boot_cpu_has(X86_FEATURE_XENPV))
|
||||
cpu0_hotpluggable = 0;
|
||||
|
||||
/*
|
||||
|
@ -85,10 +85,9 @@ pgd_t * __init efi_call_phys_prolog(void)
|
||||
|
||||
void __init efi_call_phys_epilog(pgd_t *save_pgd)
|
||||
{
|
||||
load_fixmap_gdt(0);
|
||||
load_cr3(save_pgd);
|
||||
__flush_tlb_all();
|
||||
|
||||
load_fixmap_gdt(0);
|
||||
}
|
||||
|
||||
void __init efi_runtime_update_mappings(void)
|
||||
|
@ -4,6 +4,7 @@ config ZONE_DMA
|
||||
|
||||
config XTENSA
|
||||
def_bool y
|
||||
select ARCH_HAS_SG_CHAIN
|
||||
select ARCH_HAS_SYNC_DMA_FOR_CPU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
|
||||
select ARCH_NO_COHERENT_DMA_MMAP if !MMU
|
||||
|
@ -64,11 +64,7 @@ endif
|
||||
vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y))
|
||||
plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y))
|
||||
|
||||
ifeq ($(KBUILD_SRC),)
|
||||
KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(vardirs) $(plfdirs))
|
||||
else
|
||||
KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(vardirs) $(plfdirs))
|
||||
endif
|
||||
|
||||
KBUILD_DEFCONFIG := iss_defconfig
|
||||
|
||||
|
@ -78,23 +78,28 @@ static struct notifier_block iss_panic_block = {
|
||||
|
||||
void __init platform_setup(char **p_cmdline)
|
||||
{
|
||||
static void *argv[COMMAND_LINE_SIZE / sizeof(void *)] __initdata;
|
||||
static char cmdline[COMMAND_LINE_SIZE] __initdata;
|
||||
int argc = simc_argc();
|
||||
int argv_size = simc_argv_size();
|
||||
|
||||
if (argc > 1) {
|
||||
void **argv = alloc_bootmem(argv_size);
|
||||
char *cmdline = alloc_bootmem(argv_size);
|
||||
int i;
|
||||
if (argv_size > sizeof(argv)) {
|
||||
pr_err("%s: command line too long: argv_size = %d\n",
|
||||
__func__, argv_size);
|
||||
} else {
|
||||
int i;
|
||||
|
||||
cmdline[0] = 0;
|
||||
simc_argv((void *)argv);
|
||||
cmdline[0] = 0;
|
||||
simc_argv((void *)argv);
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (i > 1)
|
||||
strcat(cmdline, " ");
|
||||
strcat(cmdline, argv[i]);
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (i > 1)
|
||||
strcat(cmdline, " ");
|
||||
strcat(cmdline, argv[i]);
|
||||
}
|
||||
*p_cmdline = cmdline;
|
||||
}
|
||||
*p_cmdline = cmdline;
|
||||
}
|
||||
|
||||
atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
|
||||
|
@ -1510,8 +1510,10 @@ int blkcg_policy_register(struct blkcg_policy *pol)
|
||||
for (i = 0; i < BLKCG_MAX_POLS; i++)
|
||||
if (!blkcg_policy[i])
|
||||
break;
|
||||
if (i >= BLKCG_MAX_POLS)
|
||||
if (i >= BLKCG_MAX_POLS) {
|
||||
pr_warn("blkcg_policy_register: BLKCG_MAX_POLS too small\n");
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
/* Make sure cpd/pd_alloc_fn and cpd/pd_free_fn in pairs */
|
||||
if ((!pol->cpd_alloc_fn ^ !pol->cpd_free_fn) ||
|
||||
|
@ -332,6 +332,35 @@ err_no_vma:
|
||||
return vma ? -ENOMEM : -ESRCH;
|
||||
}
|
||||
|
||||
|
||||
static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
if (vma)
|
||||
alloc->vma_vm_mm = vma->vm_mm;
|
||||
/*
|
||||
* If we see alloc->vma is not NULL, buffer data structures set up
|
||||
* completely. Look at smp_rmb side binder_alloc_get_vma.
|
||||
* We also want to guarantee new alloc->vma_vm_mm is always visible
|
||||
* if alloc->vma is set.
|
||||
*/
|
||||
smp_wmb();
|
||||
alloc->vma = vma;
|
||||
}
|
||||
|
||||
static inline struct vm_area_struct *binder_alloc_get_vma(
|
||||
struct binder_alloc *alloc)
|
||||
{
|
||||
struct vm_area_struct *vma = NULL;
|
||||
|
||||
if (alloc->vma) {
|
||||
/* Look at description in binder_alloc_set_vma */
|
||||
smp_rmb();
|
||||
vma = alloc->vma;
|
||||
}
|
||||
return vma;
|
||||
}
|
||||
|
||||
static struct binder_buffer *binder_alloc_new_buf_locked(
|
||||
struct binder_alloc *alloc,
|
||||
size_t data_size,
|
||||
@ -348,7 +377,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
|
||||
size_t size, data_offsets_size;
|
||||
int ret;
|
||||
|
||||
if (alloc->vma == NULL) {
|
||||
if (!binder_alloc_get_vma(alloc)) {
|
||||
binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
|
||||
"%d: binder_alloc_buf, no vma\n",
|
||||
alloc->pid);
|
||||
@ -723,9 +752,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
|
||||
buffer->free = 1;
|
||||
binder_insert_free_buffer(alloc, buffer);
|
||||
alloc->free_async_space = alloc->buffer_size / 2;
|
||||
barrier();
|
||||
alloc->vma = vma;
|
||||
alloc->vma_vm_mm = vma->vm_mm;
|
||||
binder_alloc_set_vma(alloc, vma);
|
||||
mmgrab(alloc->vma_vm_mm);
|
||||
|
||||
return 0;
|
||||
@ -754,10 +781,10 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
|
||||
int buffers, page_count;
|
||||
struct binder_buffer *buffer;
|
||||
|
||||
BUG_ON(alloc->vma);
|
||||
|
||||
buffers = 0;
|
||||
mutex_lock(&alloc->mutex);
|
||||
BUG_ON(alloc->vma);
|
||||
|
||||
while ((n = rb_first(&alloc->allocated_buffers))) {
|
||||
buffer = rb_entry(n, struct binder_buffer, rb_node);
|
||||
|
||||
@ -900,7 +927,7 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)
|
||||
*/
|
||||
void binder_alloc_vma_close(struct binder_alloc *alloc)
|
||||
{
|
||||
WRITE_ONCE(alloc->vma, NULL);
|
||||
binder_alloc_set_vma(alloc, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -935,7 +962,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
|
||||
|
||||
index = page - alloc->pages;
|
||||
page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
|
||||
vma = alloc->vma;
|
||||
vma = binder_alloc_get_vma(alloc);
|
||||
if (vma) {
|
||||
if (!mmget_not_zero(alloc->vma_vm_mm))
|
||||
goto err_mmget;
|
||||
|
@ -209,21 +209,24 @@ static struct fw_priv *__lookup_fw_priv(const char *fw_name)
|
||||
static int alloc_lookup_fw_priv(const char *fw_name,
|
||||
struct firmware_cache *fwc,
|
||||
struct fw_priv **fw_priv, void *dbuf,
|
||||
size_t size)
|
||||
size_t size, enum fw_opt opt_flags)
|
||||
{
|
||||
struct fw_priv *tmp;
|
||||
|
||||
spin_lock(&fwc->lock);
|
||||
tmp = __lookup_fw_priv(fw_name);
|
||||
if (tmp) {
|
||||
kref_get(&tmp->ref);
|
||||
spin_unlock(&fwc->lock);
|
||||
*fw_priv = tmp;
|
||||
pr_debug("batched request - sharing the same struct fw_priv and lookup for multiple requests\n");
|
||||
return 1;
|
||||
if (!(opt_flags & FW_OPT_NOCACHE)) {
|
||||
tmp = __lookup_fw_priv(fw_name);
|
||||
if (tmp) {
|
||||
kref_get(&tmp->ref);
|
||||
spin_unlock(&fwc->lock);
|
||||
*fw_priv = tmp;
|
||||
pr_debug("batched request - sharing the same struct fw_priv and lookup for multiple requests\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size);
|
||||
if (tmp)
|
||||
if (tmp && !(opt_flags & FW_OPT_NOCACHE))
|
||||
list_add(&tmp->list, &fwc->head);
|
||||
spin_unlock(&fwc->lock);
|
||||
|
||||
@ -493,7 +496,8 @@ int assign_fw(struct firmware *fw, struct device *device,
|
||||
*/
|
||||
static int
|
||||
_request_firmware_prepare(struct firmware **firmware_p, const char *name,
|
||||
struct device *device, void *dbuf, size_t size)
|
||||
struct device *device, void *dbuf, size_t size,
|
||||
enum fw_opt opt_flags)
|
||||
{
|
||||
struct firmware *firmware;
|
||||
struct fw_priv *fw_priv;
|
||||
@ -511,7 +515,8 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
|
||||
return 0; /* assigned */
|
||||
}
|
||||
|
||||
ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size);
|
||||
ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size,
|
||||
opt_flags);
|
||||
|
||||
/*
|
||||
* bind with 'priv' now to avoid warning in failure path
|
||||
@ -571,7 +576,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = _request_firmware_prepare(&fw, name, device, buf, size);
|
||||
ret = _request_firmware_prepare(&fw, name, device, buf, size,
|
||||
opt_flags);
|
||||
if (ret <= 0) /* error or already assigned */
|
||||
goto out;
|
||||
|
||||
|
@ -87,10 +87,10 @@ struct nullb {
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
int null_zone_init(struct nullb_device *dev);
|
||||
void null_zone_exit(struct nullb_device *dev);
|
||||
blk_status_t null_zone_report(struct nullb *nullb,
|
||||
struct nullb_cmd *cmd);
|
||||
void null_zone_write(struct nullb_cmd *cmd);
|
||||
void null_zone_reset(struct nullb_cmd *cmd);
|
||||
blk_status_t null_zone_report(struct nullb *nullb, struct bio *bio);
|
||||
void null_zone_write(struct nullb_cmd *cmd, sector_t sector,
|
||||
unsigned int nr_sectors);
|
||||
void null_zone_reset(struct nullb_cmd *cmd, sector_t sector);
|
||||
#else
|
||||
static inline int null_zone_init(struct nullb_device *dev)
|
||||
{
|
||||
@ -98,11 +98,14 @@ static inline int null_zone_init(struct nullb_device *dev)
|
||||
}
|
||||
static inline void null_zone_exit(struct nullb_device *dev) {}
|
||||
static inline blk_status_t null_zone_report(struct nullb *nullb,
|
||||
struct nullb_cmd *cmd)
|
||||
struct bio *bio)
|
||||
{
|
||||
return BLK_STS_NOTSUPP;
|
||||
}
|
||||
static inline void null_zone_write(struct nullb_cmd *cmd) {}
|
||||
static inline void null_zone_reset(struct nullb_cmd *cmd) {}
|
||||
static inline void null_zone_write(struct nullb_cmd *cmd, sector_t sector,
|
||||
unsigned int nr_sectors)
|
||||
{
|
||||
}
|
||||
static inline void null_zone_reset(struct nullb_cmd *cmd, sector_t sector) {}
|
||||
#endif /* CONFIG_BLK_DEV_ZONED */
|
||||
#endif /* __NULL_BLK_H */
|
||||
|
@ -1157,16 +1157,33 @@ static void null_restart_queue_async(struct nullb *nullb)
|
||||
}
|
||||
}
|
||||
|
||||
static bool cmd_report_zone(struct nullb *nullb, struct nullb_cmd *cmd)
|
||||
{
|
||||
struct nullb_device *dev = cmd->nq->dev;
|
||||
|
||||
if (dev->queue_mode == NULL_Q_BIO) {
|
||||
if (bio_op(cmd->bio) == REQ_OP_ZONE_REPORT) {
|
||||
cmd->error = null_zone_report(nullb, cmd->bio);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (req_op(cmd->rq) == REQ_OP_ZONE_REPORT) {
|
||||
cmd->error = null_zone_report(nullb, cmd->rq->bio);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static blk_status_t null_handle_cmd(struct nullb_cmd *cmd)
|
||||
{
|
||||
struct nullb_device *dev = cmd->nq->dev;
|
||||
struct nullb *nullb = dev->nullb;
|
||||
int err = 0;
|
||||
|
||||
if (req_op(cmd->rq) == REQ_OP_ZONE_REPORT) {
|
||||
cmd->error = null_zone_report(nullb, cmd);
|
||||
if (cmd_report_zone(nullb, cmd))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(NULLB_DEV_FL_THROTTLED, &dev->flags)) {
|
||||
struct request *rq = cmd->rq;
|
||||
@ -1234,10 +1251,24 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd)
|
||||
cmd->error = errno_to_blk_status(err);
|
||||
|
||||
if (!cmd->error && dev->zoned) {
|
||||
if (req_op(cmd->rq) == REQ_OP_WRITE)
|
||||
null_zone_write(cmd);
|
||||
else if (req_op(cmd->rq) == REQ_OP_ZONE_RESET)
|
||||
null_zone_reset(cmd);
|
||||
sector_t sector;
|
||||
unsigned int nr_sectors;
|
||||
int op;
|
||||
|
||||
if (dev->queue_mode == NULL_Q_BIO) {
|
||||
op = bio_op(cmd->bio);
|
||||
sector = cmd->bio->bi_iter.bi_sector;
|
||||
nr_sectors = cmd->bio->bi_iter.bi_size >> 9;
|
||||
} else {
|
||||
op = req_op(cmd->rq);
|
||||
sector = blk_rq_pos(cmd->rq);
|
||||
nr_sectors = blk_rq_sectors(cmd->rq);
|
||||
}
|
||||
|
||||
if (op == REQ_OP_WRITE)
|
||||
null_zone_write(cmd, sector, nr_sectors);
|
||||
else if (op == REQ_OP_ZONE_RESET)
|
||||
null_zone_reset(cmd, sector);
|
||||
}
|
||||
out:
|
||||
/* Complete IO by inline, softirq or timer */
|
||||
|
@ -48,8 +48,8 @@ void null_zone_exit(struct nullb_device *dev)
|
||||
kvfree(dev->zones);
|
||||
}
|
||||
|
||||
static void null_zone_fill_rq(struct nullb_device *dev, struct request *rq,
|
||||
unsigned int zno, unsigned int nr_zones)
|
||||
static void null_zone_fill_bio(struct nullb_device *dev, struct bio *bio,
|
||||
unsigned int zno, unsigned int nr_zones)
|
||||
{
|
||||
struct blk_zone_report_hdr *hdr = NULL;
|
||||
struct bio_vec bvec;
|
||||
@ -57,7 +57,7 @@ static void null_zone_fill_rq(struct nullb_device *dev, struct request *rq,
|
||||
void *addr;
|
||||
unsigned int zones_to_cpy;
|
||||
|
||||
bio_for_each_segment(bvec, rq->bio, iter) {
|
||||
bio_for_each_segment(bvec, bio, iter) {
|
||||
addr = kmap_atomic(bvec.bv_page);
|
||||
|
||||
zones_to_cpy = bvec.bv_len / sizeof(struct blk_zone);
|
||||
@ -84,29 +84,24 @@ static void null_zone_fill_rq(struct nullb_device *dev, struct request *rq,
|
||||
}
|
||||
}
|
||||
|
||||
blk_status_t null_zone_report(struct nullb *nullb,
|
||||
struct nullb_cmd *cmd)
|
||||
blk_status_t null_zone_report(struct nullb *nullb, struct bio *bio)
|
||||
{
|
||||
struct nullb_device *dev = nullb->dev;
|
||||
struct request *rq = cmd->rq;
|
||||
unsigned int zno = null_zone_no(dev, blk_rq_pos(rq));
|
||||
unsigned int zno = null_zone_no(dev, bio->bi_iter.bi_sector);
|
||||
unsigned int nr_zones = dev->nr_zones - zno;
|
||||
unsigned int max_zones = (blk_rq_bytes(rq) /
|
||||
sizeof(struct blk_zone)) - 1;
|
||||
unsigned int max_zones;
|
||||
|
||||
max_zones = (bio->bi_iter.bi_size / sizeof(struct blk_zone)) - 1;
|
||||
nr_zones = min_t(unsigned int, nr_zones, max_zones);
|
||||
|
||||
null_zone_fill_rq(nullb->dev, rq, zno, nr_zones);
|
||||
null_zone_fill_bio(nullb->dev, bio, zno, nr_zones);
|
||||
|
||||
return BLK_STS_OK;
|
||||
}
|
||||
|
||||
void null_zone_write(struct nullb_cmd *cmd)
|
||||
void null_zone_write(struct nullb_cmd *cmd, sector_t sector,
|
||||
unsigned int nr_sectors)
|
||||
{
|
||||
struct nullb_device *dev = cmd->nq->dev;
|
||||
struct request *rq = cmd->rq;
|
||||
sector_t sector = blk_rq_pos(rq);
|
||||
unsigned int rq_sectors = blk_rq_sectors(rq);
|
||||
unsigned int zno = null_zone_no(dev, sector);
|
||||
struct blk_zone *zone = &dev->zones[zno];
|
||||
|
||||
@ -118,7 +113,7 @@ void null_zone_write(struct nullb_cmd *cmd)
|
||||
case BLK_ZONE_COND_EMPTY:
|
||||
case BLK_ZONE_COND_IMP_OPEN:
|
||||
/* Writes must be at the write pointer position */
|
||||
if (blk_rq_pos(rq) != zone->wp) {
|
||||
if (sector != zone->wp) {
|
||||
cmd->error = BLK_STS_IOERR;
|
||||
break;
|
||||
}
|
||||
@ -126,7 +121,7 @@ void null_zone_write(struct nullb_cmd *cmd)
|
||||
if (zone->cond == BLK_ZONE_COND_EMPTY)
|
||||
zone->cond = BLK_ZONE_COND_IMP_OPEN;
|
||||
|
||||
zone->wp += rq_sectors;
|
||||
zone->wp += nr_sectors;
|
||||
if (zone->wp == zone->start + zone->len)
|
||||
zone->cond = BLK_ZONE_COND_FULL;
|
||||
break;
|
||||
@ -137,11 +132,10 @@ void null_zone_write(struct nullb_cmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
void null_zone_reset(struct nullb_cmd *cmd)
|
||||
void null_zone_reset(struct nullb_cmd *cmd, sector_t sector)
|
||||
{
|
||||
struct nullb_device *dev = cmd->nq->dev;
|
||||
struct request *rq = cmd->rq;
|
||||
unsigned int zno = null_zone_no(dev, blk_rq_pos(rq));
|
||||
unsigned int zno = null_zone_no(dev, sector);
|
||||
struct blk_zone *zone = &dev->zones[zno];
|
||||
|
||||
zone->cond = BLK_ZONE_COND_EMPTY;
|
||||
|
@ -543,6 +543,8 @@ static void hci_uart_tty_close(struct tty_struct *tty)
|
||||
}
|
||||
clear_bit(HCI_UART_PROTO_SET, &hu->flags);
|
||||
|
||||
percpu_free_rwsem(&hu->proto_lock);
|
||||
|
||||
kfree(hu);
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,6 @@ enum bt_states {
|
||||
BT_STATE_RESET3,
|
||||
BT_STATE_RESTART,
|
||||
BT_STATE_PRINTME,
|
||||
BT_STATE_CAPABILITIES_BEGIN,
|
||||
BT_STATE_CAPABILITIES_END,
|
||||
BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */
|
||||
};
|
||||
|
||||
@ -86,7 +84,6 @@ struct si_sm_data {
|
||||
int error_retries; /* end of "common" fields */
|
||||
int nonzero_status; /* hung BMCs stay all 0 */
|
||||
enum bt_states complete; /* to divert the state machine */
|
||||
int BT_CAP_outreqs;
|
||||
long BT_CAP_req2rsp;
|
||||
int BT_CAP_retries; /* Recommended retries */
|
||||
};
|
||||
@ -137,8 +134,6 @@ static char *state2txt(unsigned char state)
|
||||
case BT_STATE_RESET3: return("RESET3");
|
||||
case BT_STATE_RESTART: return("RESTART");
|
||||
case BT_STATE_LONG_BUSY: return("LONG_BUSY");
|
||||
case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN");
|
||||
case BT_STATE_CAPABILITIES_END: return("CAP_END");
|
||||
}
|
||||
return("BAD STATE");
|
||||
}
|
||||
@ -185,7 +180,6 @@ static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
|
||||
bt->complete = BT_STATE_IDLE; /* end here */
|
||||
bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * USEC_PER_SEC;
|
||||
bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT;
|
||||
/* BT_CAP_outreqs == zero is a flag to read BT Capabilities */
|
||||
return 3; /* We claim 3 bytes of space; ought to check SPMI table */
|
||||
}
|
||||
|
||||
@ -451,7 +445,7 @@ static enum si_sm_result error_recovery(struct si_sm_data *bt,
|
||||
|
||||
static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
|
||||
{
|
||||
unsigned char status, BT_CAP[8];
|
||||
unsigned char status;
|
||||
static enum bt_states last_printed = BT_STATE_PRINTME;
|
||||
int i;
|
||||
|
||||
@ -504,12 +498,6 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
|
||||
if (status & BT_H_BUSY) /* clear a leftover H_BUSY */
|
||||
BT_CONTROL(BT_H_BUSY);
|
||||
|
||||
bt->timeout = bt->BT_CAP_req2rsp;
|
||||
|
||||
/* Read BT capabilities if it hasn't been done yet */
|
||||
if (!bt->BT_CAP_outreqs)
|
||||
BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
|
||||
SI_SM_CALL_WITHOUT_DELAY);
|
||||
BT_SI_SM_RETURN(SI_SM_IDLE);
|
||||
|
||||
case BT_STATE_XACTION_START:
|
||||
@ -614,37 +602,6 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
|
||||
BT_STATE_CHANGE(BT_STATE_XACTION_START,
|
||||
SI_SM_CALL_WITH_DELAY);
|
||||
|
||||
/*
|
||||
* Get BT Capabilities, using timing of upper level state machine.
|
||||
* Set outreqs to prevent infinite loop on timeout.
|
||||
*/
|
||||
case BT_STATE_CAPABILITIES_BEGIN:
|
||||
bt->BT_CAP_outreqs = 1;
|
||||
{
|
||||
unsigned char GetBT_CAP[] = { 0x18, 0x36 };
|
||||
bt->state = BT_STATE_IDLE;
|
||||
bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
|
||||
}
|
||||
bt->complete = BT_STATE_CAPABILITIES_END;
|
||||
BT_STATE_CHANGE(BT_STATE_XACTION_START,
|
||||
SI_SM_CALL_WITH_DELAY);
|
||||
|
||||
case BT_STATE_CAPABILITIES_END:
|
||||
i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
|
||||
bt_init_data(bt, bt->io);
|
||||
if ((i == 8) && !BT_CAP[2]) {
|
||||
bt->BT_CAP_outreqs = BT_CAP[3];
|
||||
bt->BT_CAP_req2rsp = BT_CAP[6] * USEC_PER_SEC;
|
||||
bt->BT_CAP_retries = BT_CAP[7];
|
||||
} else
|
||||
printk(KERN_WARNING "IPMI BT: using default values\n");
|
||||
if (!bt->BT_CAP_outreqs)
|
||||
bt->BT_CAP_outreqs = 1;
|
||||
printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
|
||||
bt->BT_CAP_req2rsp / USEC_PER_SEC, bt->BT_CAP_retries);
|
||||
bt->timeout = bt->BT_CAP_req2rsp;
|
||||
return SI_SM_CALL_WITHOUT_DELAY;
|
||||
|
||||
default: /* should never occur */
|
||||
return error_recovery(bt,
|
||||
status,
|
||||
@ -655,6 +612,11 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
|
||||
|
||||
static int bt_detect(struct si_sm_data *bt)
|
||||
{
|
||||
unsigned char GetBT_CAP[] = { 0x18, 0x36 };
|
||||
unsigned char BT_CAP[8];
|
||||
enum si_sm_result smi_result;
|
||||
int rv;
|
||||
|
||||
/*
|
||||
* It's impossible for the BT status and interrupt registers to be
|
||||
* all 1's, (assuming a properly functioning, self-initialized BMC)
|
||||
@ -665,6 +627,48 @@ static int bt_detect(struct si_sm_data *bt)
|
||||
if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
|
||||
return 1;
|
||||
reset_flags(bt);
|
||||
|
||||
/*
|
||||
* Try getting the BT capabilities here.
|
||||
*/
|
||||
rv = bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
|
||||
if (rv) {
|
||||
dev_warn(bt->io->dev,
|
||||
"Can't start capabilities transaction: %d\n", rv);
|
||||
goto out_no_bt_cap;
|
||||
}
|
||||
|
||||
smi_result = SI_SM_CALL_WITHOUT_DELAY;
|
||||
for (;;) {
|
||||
if (smi_result == SI_SM_CALL_WITH_DELAY ||
|
||||
smi_result == SI_SM_CALL_WITH_TICK_DELAY) {
|
||||
schedule_timeout_uninterruptible(1);
|
||||
smi_result = bt_event(bt, jiffies_to_usecs(1));
|
||||
} else if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
|
||||
smi_result = bt_event(bt, 0);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
rv = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
|
||||
bt_init_data(bt, bt->io);
|
||||
if (rv < 8) {
|
||||
dev_warn(bt->io->dev, "bt cap response too short: %d\n", rv);
|
||||
goto out_no_bt_cap;
|
||||
}
|
||||
|
||||
if (BT_CAP[2]) {
|
||||
dev_warn(bt->io->dev, "Error fetching bt cap: %x\n", BT_CAP[2]);
|
||||
out_no_bt_cap:
|
||||
dev_warn(bt->io->dev, "using default values\n");
|
||||
} else {
|
||||
bt->BT_CAP_req2rsp = BT_CAP[6] * USEC_PER_SEC;
|
||||
bt->BT_CAP_retries = BT_CAP[7];
|
||||
}
|
||||
|
||||
dev_info(bt->io->dev, "req2rsp=%ld secs retries=%d\n",
|
||||
bt->BT_CAP_req2rsp / USEC_PER_SEC, bt->BT_CAP_retries);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3381,39 +3381,45 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
|
||||
|
||||
rv = handlers->start_processing(send_info, intf);
|
||||
if (rv)
|
||||
goto out;
|
||||
goto out_err;
|
||||
|
||||
rv = __bmc_get_device_id(intf, NULL, &id, NULL, NULL, i);
|
||||
if (rv) {
|
||||
dev_err(si_dev, "Unable to get the device id: %d\n", rv);
|
||||
goto out;
|
||||
goto out_err_started;
|
||||
}
|
||||
|
||||
mutex_lock(&intf->bmc_reg_mutex);
|
||||
rv = __scan_channels(intf, &id);
|
||||
mutex_unlock(&intf->bmc_reg_mutex);
|
||||
if (rv)
|
||||
goto out_err_bmc_reg;
|
||||
|
||||
out:
|
||||
if (rv) {
|
||||
ipmi_bmc_unregister(intf);
|
||||
list_del_rcu(&intf->link);
|
||||
mutex_unlock(&ipmi_interfaces_mutex);
|
||||
synchronize_srcu(&ipmi_interfaces_srcu);
|
||||
cleanup_srcu_struct(&intf->users_srcu);
|
||||
kref_put(&intf->refcount, intf_free);
|
||||
} else {
|
||||
/*
|
||||
* Keep memory order straight for RCU readers. Make
|
||||
* sure everything else is committed to memory before
|
||||
* setting intf_num to mark the interface valid.
|
||||
*/
|
||||
smp_wmb();
|
||||
intf->intf_num = i;
|
||||
mutex_unlock(&ipmi_interfaces_mutex);
|
||||
/*
|
||||
* Keep memory order straight for RCU readers. Make
|
||||
* sure everything else is committed to memory before
|
||||
* setting intf_num to mark the interface valid.
|
||||
*/
|
||||
smp_wmb();
|
||||
intf->intf_num = i;
|
||||
mutex_unlock(&ipmi_interfaces_mutex);
|
||||
|
||||
/* After this point the interface is legal to use. */
|
||||
call_smi_watchers(i, intf->si_dev);
|
||||
}
|
||||
/* After this point the interface is legal to use. */
|
||||
call_smi_watchers(i, intf->si_dev);
|
||||
|
||||
return 0;
|
||||
|
||||
out_err_bmc_reg:
|
||||
ipmi_bmc_unregister(intf);
|
||||
out_err_started:
|
||||
if (intf->handlers->shutdown)
|
||||
intf->handlers->shutdown(intf->send_info);
|
||||
out_err:
|
||||
list_del_rcu(&intf->link);
|
||||
mutex_unlock(&ipmi_interfaces_mutex);
|
||||
synchronize_srcu(&ipmi_interfaces_srcu);
|
||||
cleanup_srcu_struct(&intf->users_srcu);
|
||||
kref_put(&intf->refcount, intf_free);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -3504,7 +3510,8 @@ void ipmi_unregister_smi(struct ipmi_smi *intf)
|
||||
}
|
||||
srcu_read_unlock(&intf->users_srcu, index);
|
||||
|
||||
intf->handlers->shutdown(intf->send_info);
|
||||
if (intf->handlers->shutdown)
|
||||
intf->handlers->shutdown(intf->send_info);
|
||||
|
||||
cleanup_smi_msgs(intf);
|
||||
|
||||
|
@ -2083,18 +2083,9 @@ static int try_smi_init(struct smi_info *new_smi)
|
||||
si_to_str[new_smi->io.si_type]);
|
||||
|
||||
WARN_ON(new_smi->io.dev->init_name != NULL);
|
||||
|
||||
out_err:
|
||||
kfree(init_name);
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
if (new_smi->intf) {
|
||||
ipmi_unregister_smi(new_smi->intf);
|
||||
new_smi->intf = NULL;
|
||||
}
|
||||
|
||||
kfree(init_name);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2227,6 +2218,8 @@ static void shutdown_smi(void *send_info)
|
||||
|
||||
kfree(smi_info->si_sm);
|
||||
smi_info->si_sm = NULL;
|
||||
|
||||
smi_info->intf = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2240,10 +2233,8 @@ static void cleanup_one_si(struct smi_info *smi_info)
|
||||
|
||||
list_del(&smi_info->link);
|
||||
|
||||
if (smi_info->intf) {
|
||||
if (smi_info->intf)
|
||||
ipmi_unregister_smi(smi_info->intf);
|
||||
smi_info->intf = NULL;
|
||||
}
|
||||
|
||||
if (smi_info->pdev) {
|
||||
if (smi_info->pdev_registered)
|
||||
|
@ -181,6 +181,8 @@ struct ssif_addr_info {
|
||||
struct device *dev;
|
||||
struct i2c_client *client;
|
||||
|
||||
struct i2c_client *added_client;
|
||||
|
||||
struct mutex clients_mutex;
|
||||
struct list_head clients;
|
||||
|
||||
@ -1214,18 +1216,11 @@ static void shutdown_ssif(void *send_info)
|
||||
complete(&ssif_info->wake_thread);
|
||||
kthread_stop(ssif_info->thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* No message can be outstanding now, we have removed the
|
||||
* upper layer and it permitted us to do so.
|
||||
*/
|
||||
kfree(ssif_info);
|
||||
}
|
||||
|
||||
static int ssif_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ssif_info *ssif_info = i2c_get_clientdata(client);
|
||||
struct ipmi_smi *intf;
|
||||
struct ssif_addr_info *addr_info;
|
||||
|
||||
if (!ssif_info)
|
||||
@ -1235,9 +1230,7 @@ static int ssif_remove(struct i2c_client *client)
|
||||
* After this point, we won't deliver anything asychronously
|
||||
* to the message handler. We can unregister ourself.
|
||||
*/
|
||||
intf = ssif_info->intf;
|
||||
ssif_info->intf = NULL;
|
||||
ipmi_unregister_smi(intf);
|
||||
ipmi_unregister_smi(ssif_info->intf);
|
||||
|
||||
list_for_each_entry(addr_info, &ssif_infos, link) {
|
||||
if (addr_info->client == client) {
|
||||
@ -1246,6 +1239,8 @@ static int ssif_remove(struct i2c_client *client)
|
||||
}
|
||||
}
|
||||
|
||||
kfree(ssif_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1648,15 +1643,9 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
|
||||
out:
|
||||
if (rv) {
|
||||
/*
|
||||
* Note that if addr_info->client is assigned, we
|
||||
* leave it. The i2c client hangs around even if we
|
||||
* return a failure here, and the failure here is not
|
||||
* propagated back to the i2c code. This seems to be
|
||||
* design intent, strange as it may be. But if we
|
||||
* don't leave it, ssif_platform_remove will not remove
|
||||
* the client like it should.
|
||||
*/
|
||||
if (addr_info)
|
||||
addr_info->client = NULL;
|
||||
|
||||
dev_err(&client->dev, "Unable to start IPMI SSIF: %d\n", rv);
|
||||
kfree(ssif_info);
|
||||
}
|
||||
@ -1676,7 +1665,8 @@ static int ssif_adapter_handler(struct device *adev, void *opaque)
|
||||
if (adev->type != &i2c_adapter_type)
|
||||
return 0;
|
||||
|
||||
i2c_new_device(to_i2c_adapter(adev), &addr_info->binfo);
|
||||
addr_info->added_client = i2c_new_device(to_i2c_adapter(adev),
|
||||
&addr_info->binfo);
|
||||
|
||||
if (!addr_info->adapter_name)
|
||||
return 1; /* Only try the first I2C adapter by default. */
|
||||
@ -1849,7 +1839,7 @@ static int ssif_platform_remove(struct platform_device *dev)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&ssif_infos_mutex);
|
||||
i2c_unregister_device(addr_info->client);
|
||||
i2c_unregister_device(addr_info->added_client);
|
||||
|
||||
list_del(&addr_info->link);
|
||||
kfree(addr_info);
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include "kcs_bmc.h"
|
||||
|
||||
#define DEVICE_NAME "ipmi-kcs"
|
||||
|
||||
#define KCS_MSG_BUFSIZ 1000
|
||||
|
||||
#define KCS_ZERO_DATA 0
|
||||
@ -429,8 +431,6 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel)
|
||||
if (!kcs_bmc)
|
||||
return NULL;
|
||||
|
||||
dev_set_name(dev, "ipmi-kcs%u", channel);
|
||||
|
||||
spin_lock_init(&kcs_bmc->lock);
|
||||
kcs_bmc->channel = channel;
|
||||
|
||||
@ -444,7 +444,8 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel)
|
||||
return NULL;
|
||||
|
||||
kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR;
|
||||
kcs_bmc->miscdev.name = dev_name(dev);
|
||||
kcs_bmc->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s%u",
|
||||
DEVICE_NAME, channel);
|
||||
kcs_bmc->miscdev.fops = &kcs_bmc_fops;
|
||||
|
||||
return kcs_bmc;
|
||||
|
@ -55,6 +55,7 @@ struct clk_plt_data {
|
||||
u8 nparents;
|
||||
struct clk_plt *clks[PMC_CLK_NUM];
|
||||
struct clk_lookup *mclk_lookup;
|
||||
struct clk_lookup *ether_clk_lookup;
|
||||
};
|
||||
|
||||
/* Return an index in parent table */
|
||||
@ -186,13 +187,6 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
|
||||
pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
|
||||
spin_lock_init(&pclk->lock);
|
||||
|
||||
/*
|
||||
* If the clock was already enabled by the firmware mark it as critical
|
||||
* to avoid it being gated by the clock framework if no driver owns it.
|
||||
*/
|
||||
if (plt_clk_is_enabled(&pclk->hw))
|
||||
init.flags |= CLK_IS_CRITICAL;
|
||||
|
||||
ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
|
||||
if (ret) {
|
||||
pclk = ERR_PTR(ret);
|
||||
@ -351,11 +345,20 @@ static int plt_clk_probe(struct platform_device *pdev)
|
||||
goto err_unreg_clk_plt;
|
||||
}
|
||||
|
||||
data->ether_clk_lookup = clkdev_hw_create(&data->clks[4]->hw,
|
||||
"ether_clk", NULL);
|
||||
if (!data->ether_clk_lookup) {
|
||||
err = -ENOMEM;
|
||||
goto err_drop_mclk;
|
||||
}
|
||||
|
||||
plt_clk_free_parent_names_loop(parent_names, data->nparents);
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
return 0;
|
||||
|
||||
err_drop_mclk:
|
||||
clkdev_drop(data->mclk_lookup);
|
||||
err_unreg_clk_plt:
|
||||
plt_clk_unregister_loop(data, i);
|
||||
plt_clk_unregister_parents(data);
|
||||
@ -369,6 +372,7 @@ static int plt_clk_remove(struct platform_device *pdev)
|
||||
|
||||
data = platform_get_drvdata(pdev);
|
||||
|
||||
clkdev_drop(data->ether_clk_lookup);
|
||||
clkdev_drop(data->mclk_lookup);
|
||||
plt_clk_unregister_loop(data, PMC_CLK_NUM);
|
||||
plt_clk_unregister_parents(data);
|
||||
|
@ -639,7 +639,7 @@ static struct mic_dma_device *mic_dma_dev_reg(struct mbus_device *mbdev,
|
||||
int ret;
|
||||
struct device *dev = &mbdev->dev;
|
||||
|
||||
mic_dma_dev = kzalloc(sizeof(*mic_dma_dev), GFP_KERNEL);
|
||||
mic_dma_dev = devm_kzalloc(dev, sizeof(*mic_dma_dev), GFP_KERNEL);
|
||||
if (!mic_dma_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto alloc_error;
|
||||
@ -664,7 +664,6 @@ static struct mic_dma_device *mic_dma_dev_reg(struct mbus_device *mbdev,
|
||||
reg_error:
|
||||
mic_dma_uninit(mic_dma_dev);
|
||||
init_error:
|
||||
kfree(mic_dma_dev);
|
||||
mic_dma_dev = NULL;
|
||||
alloc_error:
|
||||
dev_err(dev, "Error at %s %d ret=%d\n", __func__, __LINE__, ret);
|
||||
@ -674,7 +673,6 @@ alloc_error:
|
||||
static void mic_dma_dev_unreg(struct mic_dma_device *mic_dma_dev)
|
||||
{
|
||||
mic_dma_uninit(mic_dma_dev);
|
||||
kfree(mic_dma_dev);
|
||||
}
|
||||
|
||||
/* DEBUGFS CODE */
|
||||
|
@ -420,7 +420,7 @@ static int pr_mgmt_init(struct platform_device *pdev,
|
||||
/* Create region for each port */
|
||||
fme_region = dfl_fme_create_region(pdata, mgr,
|
||||
fme_br->br, i);
|
||||
if (!fme_region) {
|
||||
if (IS_ERR(fme_region)) {
|
||||
ret = PTR_ERR(fme_region);
|
||||
goto destroy_region;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
|
||||
{
|
||||
struct drm_gem_object *gobj;
|
||||
unsigned long size;
|
||||
int r;
|
||||
|
||||
gobj = drm_gem_object_lookup(p->filp, data->handle);
|
||||
if (gobj == NULL)
|
||||
@ -50,20 +51,26 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
|
||||
p->uf_entry.tv.shared = true;
|
||||
p->uf_entry.user_pages = NULL;
|
||||
|
||||
drm_gem_object_put_unlocked(gobj);
|
||||
|
||||
size = amdgpu_bo_size(p->uf_entry.robj);
|
||||
if (size != PAGE_SIZE || (data->offset + 8) > size)
|
||||
return -EINVAL;
|
||||
if (size != PAGE_SIZE || (data->offset + 8) > size) {
|
||||
r = -EINVAL;
|
||||
goto error_unref;
|
||||
}
|
||||
|
||||
if (amdgpu_ttm_tt_get_usermm(p->uf_entry.robj->tbo.ttm)) {
|
||||
r = -EINVAL;
|
||||
goto error_unref;
|
||||
}
|
||||
|
||||
*offset = data->offset;
|
||||
|
||||
drm_gem_object_put_unlocked(gobj);
|
||||
|
||||
if (amdgpu_ttm_tt_get_usermm(p->uf_entry.robj->tbo.ttm)) {
|
||||
amdgpu_bo_unref(&p->uf_entry.robj);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_unref:
|
||||
amdgpu_bo_unref(&p->uf_entry.robj);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p,
|
||||
@ -1262,10 +1269,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
||||
error_abort:
|
||||
dma_fence_put(&job->base.s_fence->finished);
|
||||
job->base.s_fence = NULL;
|
||||
amdgpu_mn_unlock(p->mn);
|
||||
|
||||
error_unlock:
|
||||
amdgpu_job_free(job);
|
||||
amdgpu_mn_unlock(p->mn);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -2063,6 +2063,7 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev)
|
||||
static enum amd_ip_block_type ip_order[] = {
|
||||
AMD_IP_BLOCK_TYPE_GMC,
|
||||
AMD_IP_BLOCK_TYPE_COMMON,
|
||||
AMD_IP_BLOCK_TYPE_PSP,
|
||||
AMD_IP_BLOCK_TYPE_IH,
|
||||
};
|
||||
|
||||
@ -2093,7 +2094,6 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
|
||||
|
||||
static enum amd_ip_block_type ip_order[] = {
|
||||
AMD_IP_BLOCK_TYPE_SMC,
|
||||
AMD_IP_BLOCK_TYPE_PSP,
|
||||
AMD_IP_BLOCK_TYPE_DCE,
|
||||
AMD_IP_BLOCK_TYPE_GFX,
|
||||
AMD_IP_BLOCK_TYPE_SDMA,
|
||||
|
@ -70,6 +70,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_IB_CNTL, 0x800f0100, 0x00000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CLK_CTRL, 0xffffffff, 0x3f000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GFX_IB_CNTL, 0x800f0100, 0x00000100),
|
||||
@ -81,7 +82,8 @@ static const struct soc15_reg_golden golden_settings_sdma_4[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC0_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC1_IB_CNTL, 0x800f0100, 0x00000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC1_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0)
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_WATERMK, 0xfc000000, 0x00000000)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_vg10[] = {
|
||||
@ -109,7 +111,8 @@ static const struct soc15_reg_golden golden_settings_sdma_4_1[] =
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_IB_CNTL, 0x800f0111, 0x00000100),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0)
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_4_2[] =
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mmu_context.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/rbtree.h>
|
||||
@ -1792,16 +1793,21 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
|
||||
info = (struct kvmgt_guest_info *)handle;
|
||||
kvm = info->kvm;
|
||||
|
||||
if (kthread)
|
||||
if (kthread) {
|
||||
if (!mmget_not_zero(kvm->mm))
|
||||
return -EFAULT;
|
||||
use_mm(kvm->mm);
|
||||
}
|
||||
|
||||
idx = srcu_read_lock(&kvm->srcu);
|
||||
ret = write ? kvm_write_guest(kvm, gpa, buf, len) :
|
||||
kvm_read_guest(kvm, gpa, buf, len);
|
||||
srcu_read_unlock(&kvm->srcu, idx);
|
||||
|
||||
if (kthread)
|
||||
if (kthread) {
|
||||
unuse_mm(kvm->mm);
|
||||
mmput(kvm->mm);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -42,8 +42,6 @@
|
||||
#define DEVICE_TYPE_EFP3 0x20
|
||||
#define DEVICE_TYPE_EFP4 0x10
|
||||
|
||||
#define DEV_SIZE 38
|
||||
|
||||
struct opregion_header {
|
||||
u8 signature[16];
|
||||
u32 size;
|
||||
@ -63,6 +61,10 @@ struct bdb_data_header {
|
||||
u16 size; /* data size */
|
||||
} __packed;
|
||||
|
||||
/* For supporting windows guest with opregion, here hardcode the emulated
|
||||
* bdb header version as '186', and the corresponding child_device_config
|
||||
* length should be '33' but not '38'.
|
||||
*/
|
||||
struct efp_child_device_config {
|
||||
u16 handle;
|
||||
u16 device_type;
|
||||
@ -109,12 +111,6 @@ struct efp_child_device_config {
|
||||
u8 mipi_bridge_type; /* 171 */
|
||||
u16 device_class_ext;
|
||||
u8 dvo_function;
|
||||
u8 dp_usb_type_c:1; /* 195 */
|
||||
u8 skip6:7;
|
||||
u8 dp_usb_type_c_2x_gpio_index; /* 195 */
|
||||
u16 dp_usb_type_c_2x_gpio_pin; /* 195 */
|
||||
u8 iboost_dp:4; /* 196 */
|
||||
u8 iboost_hdmi:4; /* 196 */
|
||||
} __packed;
|
||||
|
||||
struct vbt {
|
||||
@ -155,7 +151,7 @@ static void virt_vbt_generation(struct vbt *v)
|
||||
v->header.bdb_offset = offsetof(struct vbt, bdb_header);
|
||||
|
||||
strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK");
|
||||
v->bdb_header.version = 186; /* child_dev_size = 38 */
|
||||
v->bdb_header.version = 186; /* child_dev_size = 33 */
|
||||
v->bdb_header.header_size = sizeof(v->bdb_header);
|
||||
|
||||
v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header)
|
||||
@ -169,11 +165,13 @@ static void virt_vbt_generation(struct vbt *v)
|
||||
|
||||
/* child device */
|
||||
num_child = 4; /* each port has one child */
|
||||
v->general_definitions.child_dev_size =
|
||||
sizeof(struct efp_child_device_config);
|
||||
v->general_definitions_header.id = BDB_GENERAL_DEFINITIONS;
|
||||
/* size will include child devices */
|
||||
v->general_definitions_header.size =
|
||||
sizeof(struct bdb_general_definitions) + num_child * DEV_SIZE;
|
||||
v->general_definitions.child_dev_size = DEV_SIZE;
|
||||
sizeof(struct bdb_general_definitions) +
|
||||
num_child * v->general_definitions.child_dev_size;
|
||||
|
||||
/* portA */
|
||||
v->child0.handle = DEVICE_TYPE_EFP1;
|
||||
|
@ -5079,10 +5079,14 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
|
||||
mutex_lock(&dev_priv->pcu_lock);
|
||||
WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
|
||||
mutex_unlock(&dev_priv->pcu_lock);
|
||||
/* wait for pcode to finish disabling IPS, which may take up to 42ms */
|
||||
/*
|
||||
* Wait for PCODE to finish disabling IPS. The BSpec specified
|
||||
* 42ms timeout value leads to occasional timeouts so use 100ms
|
||||
* instead.
|
||||
*/
|
||||
if (intel_wait_for_register(dev_priv,
|
||||
IPS_CTL, IPS_ENABLE, 0,
|
||||
42))
|
||||
100))
|
||||
DRM_ERROR("Timed out waiting for IPS disable\n");
|
||||
} else {
|
||||
I915_WRITE(IPS_CTL, 0);
|
||||
|
@ -181,8 +181,9 @@ struct intel_overlay {
|
||||
u32 brightness, contrast, saturation;
|
||||
u32 old_xscale, old_yscale;
|
||||
/* register access */
|
||||
u32 flip_addr;
|
||||
struct drm_i915_gem_object *reg_bo;
|
||||
struct overlay_registers __iomem *regs;
|
||||
u32 flip_addr;
|
||||
/* flip handling */
|
||||
struct i915_gem_active last_flip;
|
||||
};
|
||||
@ -210,29 +211,6 @@ static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv,
|
||||
PCI_DEVFN(0, 0), I830_CLOCK_GATE, val);
|
||||
}
|
||||
|
||||
static struct overlay_registers __iomem *
|
||||
intel_overlay_map_regs(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct overlay_registers __iomem *regs;
|
||||
|
||||
if (OVERLAY_NEEDS_PHYSICAL(dev_priv))
|
||||
regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr;
|
||||
else
|
||||
regs = io_mapping_map_wc(&dev_priv->ggtt.iomap,
|
||||
overlay->flip_addr,
|
||||
PAGE_SIZE);
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
||||
static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
|
||||
struct overlay_registers __iomem *regs)
|
||||
{
|
||||
if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915))
|
||||
io_mapping_unmap(regs);
|
||||
}
|
||||
|
||||
static void intel_overlay_submit_request(struct intel_overlay *overlay,
|
||||
struct i915_request *rq,
|
||||
i915_gem_retire_fn retire)
|
||||
@ -784,13 +762,13 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
struct drm_i915_gem_object *new_bo,
|
||||
struct put_image_params *params)
|
||||
{
|
||||
int ret, tmp_width;
|
||||
struct overlay_registers __iomem *regs;
|
||||
bool scale_changed = false;
|
||||
struct overlay_registers __iomem *regs = overlay->regs;
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
u32 swidth, swidthsw, sheight, ostride;
|
||||
enum pipe pipe = overlay->crtc->pipe;
|
||||
bool scale_changed = false;
|
||||
struct i915_vma *vma;
|
||||
int ret, tmp_width;
|
||||
|
||||
lockdep_assert_held(&dev_priv->drm.struct_mutex);
|
||||
WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
|
||||
@ -815,30 +793,19 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
|
||||
if (!overlay->active) {
|
||||
u32 oconfig;
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unpin;
|
||||
}
|
||||
|
||||
oconfig = OCONF_CC_OUT_8BIT;
|
||||
if (IS_GEN4(dev_priv))
|
||||
oconfig |= OCONF_CSC_MODE_BT709;
|
||||
oconfig |= pipe == 0 ?
|
||||
OCONF_PIPE_A : OCONF_PIPE_B;
|
||||
iowrite32(oconfig, ®s->OCONFIG);
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
|
||||
ret = intel_overlay_on(overlay);
|
||||
if (ret != 0)
|
||||
goto out_unpin;
|
||||
}
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unpin;
|
||||
}
|
||||
|
||||
iowrite32((params->dst_y << 16) | params->dst_x, ®s->DWINPOS);
|
||||
iowrite32((params->dst_h << 16) | params->dst_w, ®s->DWINSZ);
|
||||
|
||||
@ -882,8 +849,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
|
||||
iowrite32(overlay_cmd_reg(params), ®s->OCMD);
|
||||
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
|
||||
ret = intel_overlay_continue(overlay, vma, scale_changed);
|
||||
if (ret)
|
||||
goto out_unpin;
|
||||
@ -901,7 +866,6 @@ out_pin_section:
|
||||
int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct overlay_registers __iomem *regs;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&dev_priv->drm.struct_mutex);
|
||||
@ -918,9 +882,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
iowrite32(0, ®s->OCMD);
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
iowrite32(0, &overlay->regs->OCMD);
|
||||
|
||||
return intel_overlay_off(overlay);
|
||||
}
|
||||
@ -1305,7 +1267,6 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_intel_overlay_attrs *attrs = data;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_overlay *overlay;
|
||||
struct overlay_registers __iomem *regs;
|
||||
int ret;
|
||||
|
||||
overlay = dev_priv->overlay;
|
||||
@ -1345,15 +1306,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
overlay->contrast = attrs->contrast;
|
||||
overlay->saturation = attrs->saturation;
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
update_reg_attrs(overlay, regs);
|
||||
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
update_reg_attrs(overlay, overlay->regs);
|
||||
|
||||
if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
|
||||
if (IS_GEN2(dev_priv))
|
||||
@ -1386,12 +1339,47 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_registers(struct intel_overlay *overlay, bool use_phys)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_vma *vma;
|
||||
int err;
|
||||
|
||||
obj = i915_gem_object_create_stolen(overlay->i915, PAGE_SIZE);
|
||||
if (obj == NULL)
|
||||
obj = i915_gem_object_create_internal(overlay->i915, PAGE_SIZE);
|
||||
if (IS_ERR(obj))
|
||||
return PTR_ERR(obj);
|
||||
|
||||
vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
|
||||
if (IS_ERR(vma)) {
|
||||
err = PTR_ERR(vma);
|
||||
goto err_put_bo;
|
||||
}
|
||||
|
||||
if (use_phys)
|
||||
overlay->flip_addr = sg_dma_address(obj->mm.pages->sgl);
|
||||
else
|
||||
overlay->flip_addr = i915_ggtt_offset(vma);
|
||||
overlay->regs = i915_vma_pin_iomap(vma);
|
||||
i915_vma_unpin(vma);
|
||||
|
||||
if (IS_ERR(overlay->regs)) {
|
||||
err = PTR_ERR(overlay->regs);
|
||||
goto err_put_bo;
|
||||
}
|
||||
|
||||
overlay->reg_bo = obj;
|
||||
return 0;
|
||||
|
||||
err_put_bo:
|
||||
i915_gem_object_put(obj);
|
||||
return err;
|
||||
}
|
||||
|
||||
void intel_setup_overlay(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_overlay *overlay;
|
||||
struct drm_i915_gem_object *reg_bo;
|
||||
struct overlay_registers __iomem *regs;
|
||||
struct i915_vma *vma = NULL;
|
||||
int ret;
|
||||
|
||||
if (!HAS_OVERLAY(dev_priv))
|
||||
@ -1401,46 +1389,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
|
||||
if (!overlay)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
if (WARN_ON(dev_priv->overlay))
|
||||
goto out_free;
|
||||
|
||||
overlay->i915 = dev_priv;
|
||||
|
||||
reg_bo = NULL;
|
||||
if (!OVERLAY_NEEDS_PHYSICAL(dev_priv))
|
||||
reg_bo = i915_gem_object_create_stolen(dev_priv, PAGE_SIZE);
|
||||
if (reg_bo == NULL)
|
||||
reg_bo = i915_gem_object_create(dev_priv, PAGE_SIZE);
|
||||
if (IS_ERR(reg_bo))
|
||||
goto out_free;
|
||||
overlay->reg_bo = reg_bo;
|
||||
|
||||
if (OVERLAY_NEEDS_PHYSICAL(dev_priv)) {
|
||||
ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to attach phys overlay regs\n");
|
||||
goto out_free_bo;
|
||||
}
|
||||
overlay->flip_addr = reg_bo->phys_handle->busaddr;
|
||||
} else {
|
||||
vma = i915_gem_object_ggtt_pin(reg_bo, NULL,
|
||||
0, PAGE_SIZE, PIN_MAPPABLE);
|
||||
if (IS_ERR(vma)) {
|
||||
DRM_ERROR("failed to pin overlay register bo\n");
|
||||
ret = PTR_ERR(vma);
|
||||
goto out_free_bo;
|
||||
}
|
||||
overlay->flip_addr = i915_ggtt_offset(vma);
|
||||
|
||||
ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to move overlay register bo into the GTT\n");
|
||||
goto out_unpin_bo;
|
||||
}
|
||||
}
|
||||
|
||||
/* init all values */
|
||||
overlay->color_key = 0x0101fe;
|
||||
overlay->color_key_enabled = true;
|
||||
overlay->brightness = -19;
|
||||
@ -1449,44 +1399,51 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
|
||||
|
||||
init_request_active(&overlay->last_flip, NULL);
|
||||
|
||||
regs = intel_overlay_map_regs(overlay);
|
||||
if (!regs)
|
||||
goto out_unpin_bo;
|
||||
mutex_lock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
memset_io(regs, 0, sizeof(struct overlay_registers));
|
||||
update_polyphase_filter(regs);
|
||||
update_reg_attrs(overlay, regs);
|
||||
ret = get_registers(overlay, OVERLAY_NEEDS_PHYSICAL(dev_priv));
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
intel_overlay_unmap_regs(overlay, regs);
|
||||
ret = i915_gem_object_set_to_gtt_domain(overlay->reg_bo, true);
|
||||
if (ret)
|
||||
goto out_reg_bo;
|
||||
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
memset_io(overlay->regs, 0, sizeof(struct overlay_registers));
|
||||
update_polyphase_filter(overlay->regs);
|
||||
update_reg_attrs(overlay, overlay->regs);
|
||||
|
||||
dev_priv->overlay = overlay;
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
DRM_INFO("initialized overlay support\n");
|
||||
DRM_INFO("Initialized overlay support.\n");
|
||||
return;
|
||||
|
||||
out_unpin_bo:
|
||||
if (vma)
|
||||
i915_vma_unpin(vma);
|
||||
out_free_bo:
|
||||
i915_gem_object_put(reg_bo);
|
||||
out_reg_bo:
|
||||
i915_gem_object_put(overlay->reg_bo);
|
||||
out_free:
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
kfree(overlay);
|
||||
return;
|
||||
}
|
||||
|
||||
void intel_cleanup_overlay(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (!dev_priv->overlay)
|
||||
struct intel_overlay *overlay;
|
||||
|
||||
overlay = fetch_and_zero(&dev_priv->overlay);
|
||||
if (!overlay)
|
||||
return;
|
||||
|
||||
/* The bo's should be free'd by the generic code already.
|
||||
/*
|
||||
* The bo's should be free'd by the generic code already.
|
||||
* Furthermore modesetting teardown happens beforehand so the
|
||||
* hardware should be off already */
|
||||
WARN_ON(dev_priv->overlay->active);
|
||||
* hardware should be off already.
|
||||
*/
|
||||
WARN_ON(overlay->active);
|
||||
|
||||
i915_gem_object_put(dev_priv->overlay->reg_bo);
|
||||
kfree(dev_priv->overlay);
|
||||
i915_gem_object_put(overlay->reg_bo);
|
||||
|
||||
kfree(overlay);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
|
||||
@ -1498,37 +1455,11 @@ struct intel_overlay_error_state {
|
||||
u32 isr;
|
||||
};
|
||||
|
||||
static struct overlay_registers __iomem *
|
||||
intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct overlay_registers __iomem *regs;
|
||||
|
||||
if (OVERLAY_NEEDS_PHYSICAL(dev_priv))
|
||||
/* Cast to make sparse happy, but it's wc memory anyway, so
|
||||
* equivalent to the wc io mapping on X86. */
|
||||
regs = (struct overlay_registers __iomem *)
|
||||
overlay->reg_bo->phys_handle->vaddr;
|
||||
else
|
||||
regs = io_mapping_map_atomic_wc(&dev_priv->ggtt.iomap,
|
||||
overlay->flip_addr);
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
||||
static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
|
||||
struct overlay_registers __iomem *regs)
|
||||
{
|
||||
if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915))
|
||||
io_mapping_unmap_atomic(regs);
|
||||
}
|
||||
|
||||
struct intel_overlay_error_state *
|
||||
intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_overlay *overlay = dev_priv->overlay;
|
||||
struct intel_overlay_error_state *error;
|
||||
struct overlay_registers __iomem *regs;
|
||||
|
||||
if (!overlay || !overlay->active)
|
||||
return NULL;
|
||||
@ -1541,18 +1472,9 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
|
||||
error->isr = I915_READ(ISR);
|
||||
error->base = overlay->flip_addr;
|
||||
|
||||
regs = intel_overlay_map_regs_atomic(overlay);
|
||||
if (!regs)
|
||||
goto err;
|
||||
|
||||
memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
|
||||
intel_overlay_unmap_regs_atomic(overlay, regs);
|
||||
memcpy_fromio(&error->regs, overlay->regs, sizeof(error->regs));
|
||||
|
||||
return error;
|
||||
|
||||
err:
|
||||
kfree(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -86,10 +86,8 @@ pmu_load(struct nv50_devinit *init, u8 type, bool post,
|
||||
struct nvkm_bios *bios = subdev->device->bios;
|
||||
struct nvbios_pmuR pmu;
|
||||
|
||||
if (!nvbios_pmuRm(bios, type, &pmu)) {
|
||||
nvkm_error(subdev, "VBIOS PMU fuc %02x not found\n", type);
|
||||
if (!nvbios_pmuRm(bios, type, &pmu))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!post)
|
||||
return 0;
|
||||
@ -124,29 +122,30 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Upload DEVINIT application from VBIOS onto PMU. */
|
||||
ret = pmu_load(init, 0x04, post, &exec, &args);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
nvkm_error(subdev, "VBIOS PMU/DEVINIT not found\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* upload first chunk of init data */
|
||||
/* Upload tables required by opcodes in boot scripts. */
|
||||
if (post) {
|
||||
// devinit tables
|
||||
u32 pmu = pmu_args(init, args + 0x08, 0x08);
|
||||
u32 img = nvbios_rd16(bios, bit_I.offset + 0x14);
|
||||
u32 len = nvbios_rd16(bios, bit_I.offset + 0x16);
|
||||
pmu_data(init, pmu, img, len);
|
||||
}
|
||||
|
||||
/* upload second chunk of init data */
|
||||
/* Upload boot scripts. */
|
||||
if (post) {
|
||||
// devinit boot scripts
|
||||
u32 pmu = pmu_args(init, args + 0x08, 0x10);
|
||||
u32 img = nvbios_rd16(bios, bit_I.offset + 0x18);
|
||||
u32 len = nvbios_rd16(bios, bit_I.offset + 0x1a);
|
||||
pmu_data(init, pmu, img, len);
|
||||
}
|
||||
|
||||
/* execute init tables */
|
||||
/* Execute DEVINIT. */
|
||||
if (post) {
|
||||
nvkm_wr32(device, 0x10a040, 0x00005000);
|
||||
pmu_exec(init, exec);
|
||||
@ -157,7 +156,9 @@ gm200_devinit_post(struct nvkm_devinit *base, bool post)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* load and execute some other ucode image (bios therm?) */
|
||||
/* Optional: Execute PRE_OS application on PMU, which should at
|
||||
* least take care of fans until a full PMU has been loaded.
|
||||
*/
|
||||
pmu_load(init, 0x01, post, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1291,6 +1291,9 @@ static ssize_t vmbus_chan_attr_show(struct kobject *kobj,
|
||||
if (!attribute->show)
|
||||
return -EIO;
|
||||
|
||||
if (chan->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
|
||||
return attribute->show(chan, buf);
|
||||
}
|
||||
|
||||
|
@ -187,12 +187,15 @@ static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor,
|
||||
|
||||
int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
|
||||
{
|
||||
u16 fifo_watermark = ~0, cur_watermark, sip = 0, fifo_th_mask;
|
||||
u16 fifo_watermark = ~0, cur_watermark, fifo_th_mask;
|
||||
struct st_lsm6dsx_hw *hw = sensor->hw;
|
||||
struct st_lsm6dsx_sensor *cur_sensor;
|
||||
int i, err, data;
|
||||
__le16 wdata;
|
||||
|
||||
if (!hw->sip)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
|
||||
cur_sensor = iio_priv(hw->iio_devs[i]);
|
||||
|
||||
@ -203,14 +206,10 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
|
||||
: cur_sensor->watermark;
|
||||
|
||||
fifo_watermark = min_t(u16, fifo_watermark, cur_watermark);
|
||||
sip += cur_sensor->sip;
|
||||
}
|
||||
|
||||
if (!sip)
|
||||
return 0;
|
||||
|
||||
fifo_watermark = max_t(u16, fifo_watermark, sip);
|
||||
fifo_watermark = (fifo_watermark / sip) * sip;
|
||||
fifo_watermark = max_t(u16, fifo_watermark, hw->sip);
|
||||
fifo_watermark = (fifo_watermark / hw->sip) * hw->sip;
|
||||
fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl;
|
||||
|
||||
err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1,
|
||||
|
@ -258,7 +258,6 @@ static int maxim_thermocouple_remove(struct spi_device *spi)
|
||||
static const struct spi_device_id maxim_thermocouple_id[] = {
|
||||
{"max6675", MAX6675},
|
||||
{"max31855", MAX31855},
|
||||
{"max31856", MAX31855},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
|
||||
|
@ -893,14 +893,11 @@ static int trigger_sbr(struct hfi1_devdata *dd)
|
||||
}
|
||||
|
||||
/*
|
||||
* A secondary bus reset (SBR) issues a hot reset to our device.
|
||||
* The following routine does a 1s wait after the reset is dropped
|
||||
* per PCI Trhfa (recovery time). PCIe 3.0 section 6.6.1 -
|
||||
* Conventional Reset, paragraph 3, line 35 also says that a 1s
|
||||
* delay after a reset is required. Per spec requirements,
|
||||
* the link is either working or not after that point.
|
||||
* This is an end around to do an SBR during probe time. A new API needs
|
||||
* to be implemented to have cleaner interface but this fixes the
|
||||
* current brokenness
|
||||
*/
|
||||
return pci_reset_bus(dev);
|
||||
return pci_bridge_secondary_bus_reset(dev->bus->self);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -332,7 +332,7 @@ static int crypt_iv_essiv_init(struct crypt_config *cc)
|
||||
int err;
|
||||
|
||||
desc->tfm = essiv->hash_tfm;
|
||||
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
desc->flags = 0;
|
||||
|
||||
err = crypto_shash_digest(desc, cc->key, cc->key_size, essiv->salt);
|
||||
shash_desc_zero(desc);
|
||||
@ -606,7 +606,7 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv,
|
||||
int i, r;
|
||||
|
||||
desc->tfm = lmk->hash_tfm;
|
||||
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
desc->flags = 0;
|
||||
|
||||
r = crypto_shash_init(desc);
|
||||
if (r)
|
||||
@ -768,7 +768,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc,
|
||||
|
||||
/* calculate crc32 for every 32bit part and xor it */
|
||||
desc->tfm = tcw->crc32_tfm;
|
||||
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
desc->flags = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
r = crypto_shash_init(desc);
|
||||
if (r)
|
||||
@ -1251,7 +1251,7 @@ static void crypt_alloc_req_skcipher(struct crypt_config *cc,
|
||||
* requests if driver request queue is full.
|
||||
*/
|
||||
skcipher_request_set_callback(ctx->r.req,
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
kcryptd_async_done, dmreq_of_req(cc, ctx->r.req));
|
||||
}
|
||||
|
||||
@ -1268,7 +1268,7 @@ static void crypt_alloc_req_aead(struct crypt_config *cc,
|
||||
* requests if driver request queue is full.
|
||||
*/
|
||||
aead_request_set_callback(ctx->r.req_aead,
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
kcryptd_async_done, dmreq_of_req(cc, ctx->r.req_aead));
|
||||
}
|
||||
|
||||
|
@ -532,7 +532,7 @@ static void section_mac(struct dm_integrity_c *ic, unsigned section, __u8 result
|
||||
unsigned j, size;
|
||||
|
||||
desc->tfm = ic->journal_mac;
|
||||
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
desc->flags = 0;
|
||||
|
||||
r = crypto_shash_init(desc);
|
||||
if (unlikely(r)) {
|
||||
@ -676,7 +676,7 @@ static void complete_journal_encrypt(struct crypto_async_request *req, int err)
|
||||
static bool do_crypt(bool encrypt, struct skcipher_request *req, struct journal_completion *comp)
|
||||
{
|
||||
int r;
|
||||
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||
skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
complete_journal_encrypt, comp);
|
||||
if (likely(encrypt))
|
||||
r = crypto_skcipher_encrypt(req);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Neil Brown
|
||||
* Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is released under the GPL.
|
||||
*/
|
||||
@ -29,9 +29,6 @@
|
||||
*/
|
||||
#define MIN_RAID456_JOURNAL_SPACE (4*2048)
|
||||
|
||||
/* Global list of all raid sets */
|
||||
static LIST_HEAD(raid_sets);
|
||||
|
||||
static bool devices_handle_discard_safely = false;
|
||||
|
||||
/*
|
||||
@ -227,7 +224,6 @@ struct rs_layout {
|
||||
|
||||
struct raid_set {
|
||||
struct dm_target *ti;
|
||||
struct list_head list;
|
||||
|
||||
uint32_t stripe_cache_entries;
|
||||
unsigned long ctr_flags;
|
||||
@ -273,19 +269,6 @@ static void rs_config_restore(struct raid_set *rs, struct rs_layout *l)
|
||||
mddev->new_chunk_sectors = l->new_chunk_sectors;
|
||||
}
|
||||
|
||||
/* Find any raid_set in active slot for @rs on global list */
|
||||
static struct raid_set *rs_find_active(struct raid_set *rs)
|
||||
{
|
||||
struct raid_set *r;
|
||||
struct mapped_device *md = dm_table_get_md(rs->ti->table);
|
||||
|
||||
list_for_each_entry(r, &raid_sets, list)
|
||||
if (r != rs && dm_table_get_md(r->ti->table) == md)
|
||||
return r;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* raid10 algorithms (i.e. formats) */
|
||||
#define ALGORITHM_RAID10_DEFAULT 0
|
||||
#define ALGORITHM_RAID10_NEAR 1
|
||||
@ -764,7 +747,6 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r
|
||||
|
||||
mddev_init(&rs->md);
|
||||
|
||||
INIT_LIST_HEAD(&rs->list);
|
||||
rs->raid_disks = raid_devs;
|
||||
rs->delta_disks = 0;
|
||||
|
||||
@ -782,9 +764,6 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r
|
||||
for (i = 0; i < raid_devs; i++)
|
||||
md_rdev_init(&rs->dev[i].rdev);
|
||||
|
||||
/* Add @rs to global list. */
|
||||
list_add(&rs->list, &raid_sets);
|
||||
|
||||
/*
|
||||
* Remaining items to be initialized by further RAID params:
|
||||
* rs->md.persistent
|
||||
@ -797,7 +776,7 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r
|
||||
return rs;
|
||||
}
|
||||
|
||||
/* Free all @rs allocations and remove it from global list. */
|
||||
/* Free all @rs allocations */
|
||||
static void raid_set_free(struct raid_set *rs)
|
||||
{
|
||||
int i;
|
||||
@ -815,8 +794,6 @@ static void raid_set_free(struct raid_set *rs)
|
||||
dm_put_device(rs->ti, rs->dev[i].data_dev);
|
||||
}
|
||||
|
||||
list_del(&rs->list);
|
||||
|
||||
kfree(rs);
|
||||
}
|
||||
|
||||
@ -2649,7 +2626,7 @@ static int rs_adjust_data_offsets(struct raid_set *rs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HM FIXME: get InSync raid_dev? */
|
||||
/* HM FIXME: get In_Sync raid_dev? */
|
||||
rdev = &rs->dev[0].rdev;
|
||||
|
||||
if (rs->delta_disks < 0) {
|
||||
@ -3149,6 +3126,11 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
|
||||
rs_set_new(rs);
|
||||
} else if (rs_is_recovering(rs)) {
|
||||
/* Rebuild particular devices */
|
||||
if (test_bit(__CTR_FLAG_REBUILD, &rs->ctr_flags)) {
|
||||
set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags);
|
||||
rs_setup_recovery(rs, MaxSector);
|
||||
}
|
||||
/* A recovering raid set may be resized */
|
||||
; /* skip setup rs */
|
||||
} else if (rs_is_reshaping(rs)) {
|
||||
@ -3242,6 +3224,8 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
/* Start raid set read-only and assumed clean to change in raid_resume() */
|
||||
rs->md.ro = 1;
|
||||
rs->md.in_sync = 1;
|
||||
|
||||
/* Keep array frozen */
|
||||
set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
|
||||
|
||||
/* Has to be held on running the array */
|
||||
@ -3265,7 +3249,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
rs->callbacks.congested_fn = raid_is_congested;
|
||||
dm_table_add_target_callbacks(ti->table, &rs->callbacks);
|
||||
|
||||
/* If raid4/5/6 journal mode explictely requested (only possible with journal dev) -> set it */
|
||||
/* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */
|
||||
if (test_bit(__CTR_FLAG_JOURNAL_MODE, &rs->ctr_flags)) {
|
||||
r = r5c_journal_mode_set(&rs->md, rs->journal_dev.mode);
|
||||
if (r) {
|
||||
@ -3350,32 +3334,53 @@ static int raid_map(struct dm_target *ti, struct bio *bio)
|
||||
return DM_MAPIO_SUBMITTED;
|
||||
}
|
||||
|
||||
/* Return string describing the current sync action of @mddev */
|
||||
static const char *decipher_sync_action(struct mddev *mddev, unsigned long recovery)
|
||||
/* Return sync state string for @state */
|
||||
enum sync_state { st_frozen, st_reshape, st_resync, st_check, st_repair, st_recover, st_idle };
|
||||
static const char *sync_str(enum sync_state state)
|
||||
{
|
||||
/* Has to be in above sync_state order! */
|
||||
static const char *sync_strs[] = {
|
||||
"frozen",
|
||||
"reshape",
|
||||
"resync",
|
||||
"check",
|
||||
"repair",
|
||||
"recover",
|
||||
"idle"
|
||||
};
|
||||
|
||||
return __within_range(state, 0, ARRAY_SIZE(sync_strs) - 1) ? sync_strs[state] : "undef";
|
||||
};
|
||||
|
||||
/* Return enum sync_state for @mddev derived from @recovery flags */
|
||||
static const enum sync_state decipher_sync_action(struct mddev *mddev, unsigned long recovery)
|
||||
{
|
||||
if (test_bit(MD_RECOVERY_FROZEN, &recovery))
|
||||
return "frozen";
|
||||
return st_frozen;
|
||||
|
||||
/* The MD sync thread can be done with io but still be running */
|
||||
/* The MD sync thread can be done with io or be interrupted but still be running */
|
||||
if (!test_bit(MD_RECOVERY_DONE, &recovery) &&
|
||||
(test_bit(MD_RECOVERY_RUNNING, &recovery) ||
|
||||
(!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &recovery)))) {
|
||||
if (test_bit(MD_RECOVERY_RESHAPE, &recovery))
|
||||
return "reshape";
|
||||
return st_reshape;
|
||||
|
||||
if (test_bit(MD_RECOVERY_SYNC, &recovery)) {
|
||||
if (!test_bit(MD_RECOVERY_REQUESTED, &recovery))
|
||||
return "resync";
|
||||
else if (test_bit(MD_RECOVERY_CHECK, &recovery))
|
||||
return "check";
|
||||
return "repair";
|
||||
return st_resync;
|
||||
if (test_bit(MD_RECOVERY_CHECK, &recovery))
|
||||
return st_check;
|
||||
return st_repair;
|
||||
}
|
||||
|
||||
if (test_bit(MD_RECOVERY_RECOVER, &recovery))
|
||||
return "recover";
|
||||
return st_recover;
|
||||
|
||||
if (mddev->reshape_position != MaxSector)
|
||||
return st_reshape;
|
||||
}
|
||||
|
||||
return "idle";
|
||||
return st_idle;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3409,6 +3414,7 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
|
||||
sector_t resync_max_sectors)
|
||||
{
|
||||
sector_t r;
|
||||
enum sync_state state;
|
||||
struct mddev *mddev = &rs->md;
|
||||
|
||||
clear_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
|
||||
@ -3419,20 +3425,14 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
|
||||
set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
|
||||
|
||||
} else {
|
||||
if (!test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags) &&
|
||||
!test_bit(MD_RECOVERY_INTR, &recovery) &&
|
||||
(test_bit(MD_RECOVERY_NEEDED, &recovery) ||
|
||||
test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
|
||||
test_bit(MD_RECOVERY_RUNNING, &recovery)))
|
||||
r = mddev->curr_resync_completed;
|
||||
else
|
||||
r = mddev->recovery_cp;
|
||||
state = decipher_sync_action(mddev, recovery);
|
||||
|
||||
if (r >= resync_max_sectors &&
|
||||
(!test_bit(MD_RECOVERY_REQUESTED, &recovery) ||
|
||||
(!test_bit(MD_RECOVERY_FROZEN, &recovery) &&
|
||||
!test_bit(MD_RECOVERY_NEEDED, &recovery) &&
|
||||
!test_bit(MD_RECOVERY_RUNNING, &recovery)))) {
|
||||
if (state == st_idle && !test_bit(MD_RECOVERY_INTR, &recovery))
|
||||
r = mddev->recovery_cp;
|
||||
else
|
||||
r = mddev->curr_resync_completed;
|
||||
|
||||
if (state == st_idle && r >= resync_max_sectors) {
|
||||
/*
|
||||
* Sync complete.
|
||||
*/
|
||||
@ -3440,24 +3440,20 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
|
||||
if (test_bit(MD_RECOVERY_RECOVER, &recovery))
|
||||
set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
|
||||
|
||||
} else if (test_bit(MD_RECOVERY_RECOVER, &recovery)) {
|
||||
} else if (state == st_recover)
|
||||
/*
|
||||
* In case we are recovering, the array is not in sync
|
||||
* and health chars should show the recovering legs.
|
||||
*/
|
||||
;
|
||||
|
||||
} else if (test_bit(MD_RECOVERY_SYNC, &recovery) &&
|
||||
!test_bit(MD_RECOVERY_REQUESTED, &recovery)) {
|
||||
else if (state == st_resync)
|
||||
/*
|
||||
* If "resync" is occurring, the raid set
|
||||
* is or may be out of sync hence the health
|
||||
* characters shall be 'a'.
|
||||
*/
|
||||
set_bit(RT_FLAG_RS_RESYNCING, &rs->runtime_flags);
|
||||
|
||||
} else if (test_bit(MD_RECOVERY_RESHAPE, &recovery) &&
|
||||
!test_bit(MD_RECOVERY_REQUESTED, &recovery)) {
|
||||
else if (state == st_reshape)
|
||||
/*
|
||||
* If "reshape" is occurring, the raid set
|
||||
* is or may be out of sync hence the health
|
||||
@ -3465,7 +3461,7 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
|
||||
*/
|
||||
set_bit(RT_FLAG_RS_RESYNCING, &rs->runtime_flags);
|
||||
|
||||
} else if (test_bit(MD_RECOVERY_REQUESTED, &recovery)) {
|
||||
else if (state == st_check || state == st_repair)
|
||||
/*
|
||||
* If "check" or "repair" is occurring, the raid set has
|
||||
* undergone an initial sync and the health characters
|
||||
@ -3473,12 +3469,12 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
|
||||
*/
|
||||
set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
|
||||
|
||||
} else {
|
||||
else {
|
||||
struct md_rdev *rdev;
|
||||
|
||||
/*
|
||||
* We are idle and recovery is needed, prevent 'A' chars race
|
||||
* caused by components still set to in-sync by constrcuctor.
|
||||
* caused by components still set to in-sync by constructor.
|
||||
*/
|
||||
if (test_bit(MD_RECOVERY_NEEDED, &recovery))
|
||||
set_bit(RT_FLAG_RS_RESYNCING, &rs->runtime_flags);
|
||||
@ -3542,7 +3538,7 @@ static void raid_status(struct dm_target *ti, status_type_t type,
|
||||
progress = rs_get_progress(rs, recovery, resync_max_sectors);
|
||||
resync_mismatches = (mddev->last_sync_action && !strcasecmp(mddev->last_sync_action, "check")) ?
|
||||
atomic64_read(&mddev->resync_mismatches) : 0;
|
||||
sync_action = decipher_sync_action(&rs->md, recovery);
|
||||
sync_action = sync_str(decipher_sync_action(&rs->md, recovery));
|
||||
|
||||
/* HM FIXME: do we want another state char for raid0? It shows 'D'/'A'/'-' now */
|
||||
for (i = 0; i < rs->raid_disks; i++)
|
||||
@ -3892,14 +3888,13 @@ static int rs_start_reshape(struct raid_set *rs)
|
||||
struct mddev *mddev = &rs->md;
|
||||
struct md_personality *pers = mddev->pers;
|
||||
|
||||
/* Don't allow the sync thread to work until the table gets reloaded. */
|
||||
set_bit(MD_RECOVERY_WAIT, &mddev->recovery);
|
||||
|
||||
r = rs_setup_reshape(rs);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Need to be resumed to be able to start reshape, recovery is frozen until raid_resume() though */
|
||||
if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
|
||||
mddev_resume(mddev);
|
||||
|
||||
/*
|
||||
* Check any reshape constraints enforced by the personalility
|
||||
*
|
||||
@ -3923,10 +3918,6 @@ static int rs_start_reshape(struct raid_set *rs)
|
||||
}
|
||||
}
|
||||
|
||||
/* Suspend because a resume will happen in raid_resume() */
|
||||
set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags);
|
||||
mddev_suspend(mddev);
|
||||
|
||||
/*
|
||||
* Now reshape got set up, update superblocks to
|
||||
* reflect the fact so that a table reload will
|
||||
@ -3947,29 +3938,6 @@ static int raid_preresume(struct dm_target *ti)
|
||||
if (test_and_set_bit(RT_FLAG_RS_PRERESUMED, &rs->runtime_flags))
|
||||
return 0;
|
||||
|
||||
if (!test_bit(__CTR_FLAG_REBUILD, &rs->ctr_flags)) {
|
||||
struct raid_set *rs_active = rs_find_active(rs);
|
||||
|
||||
if (rs_active) {
|
||||
/*
|
||||
* In case no rebuilds have been requested
|
||||
* and an active table slot exists, copy
|
||||
* current resynchonization completed and
|
||||
* reshape position pointers across from
|
||||
* suspended raid set in the active slot.
|
||||
*
|
||||
* This resumes the new mapping at current
|
||||
* offsets to continue recover/reshape without
|
||||
* necessarily redoing a raid set partially or
|
||||
* causing data corruption in case of a reshape.
|
||||
*/
|
||||
if (rs_active->md.curr_resync_completed != MaxSector)
|
||||
mddev->curr_resync_completed = rs_active->md.curr_resync_completed;
|
||||
if (rs_active->md.reshape_position != MaxSector)
|
||||
mddev->reshape_position = rs_active->md.reshape_position;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The superblocks need to be updated on disk if the
|
||||
* array is new or new devices got added (thus zeroed
|
||||
@ -4046,7 +4014,7 @@ static void raid_resume(struct dm_target *ti)
|
||||
|
||||
static struct target_type raid_target = {
|
||||
.name = "raid",
|
||||
.version = {1, 13, 2},
|
||||
.version = {1, 14, 0},
|
||||
.module = THIS_MODULE,
|
||||
.ctr = raid_ctr,
|
||||
.dtr = raid_dtr,
|
||||
|
@ -188,6 +188,12 @@ struct dm_pool_metadata {
|
||||
unsigned long flags;
|
||||
sector_t data_block_size;
|
||||
|
||||
/*
|
||||
* We reserve a section of the metadata for commit overhead.
|
||||
* All reported space does *not* include this.
|
||||
*/
|
||||
dm_block_t metadata_reserve;
|
||||
|
||||
/*
|
||||
* Set if a transaction has to be aborted but the attempt to roll back
|
||||
* to the previous (good) transaction failed. The only pool metadata
|
||||
@ -816,6 +822,22 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
|
||||
return dm_tm_commit(pmd->tm, sblock);
|
||||
}
|
||||
|
||||
static void __set_metadata_reserve(struct dm_pool_metadata *pmd)
|
||||
{
|
||||
int r;
|
||||
dm_block_t total;
|
||||
dm_block_t max_blocks = 4096; /* 16M */
|
||||
|
||||
r = dm_sm_get_nr_blocks(pmd->metadata_sm, &total);
|
||||
if (r) {
|
||||
DMERR("could not get size of metadata device");
|
||||
pmd->metadata_reserve = max_blocks;
|
||||
} else {
|
||||
sector_div(total, 10);
|
||||
pmd->metadata_reserve = min(max_blocks, total);
|
||||
}
|
||||
}
|
||||
|
||||
struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
|
||||
sector_t data_block_size,
|
||||
bool format_device)
|
||||
@ -849,6 +871,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
|
||||
return ERR_PTR(r);
|
||||
}
|
||||
|
||||
__set_metadata_reserve(pmd);
|
||||
|
||||
return pmd;
|
||||
}
|
||||
|
||||
@ -1820,6 +1844,13 @@ int dm_pool_get_free_metadata_block_count(struct dm_pool_metadata *pmd,
|
||||
down_read(&pmd->root_lock);
|
||||
if (!pmd->fail_io)
|
||||
r = dm_sm_get_nr_free(pmd->metadata_sm, result);
|
||||
|
||||
if (!r) {
|
||||
if (*result < pmd->metadata_reserve)
|
||||
*result = 0;
|
||||
else
|
||||
*result -= pmd->metadata_reserve;
|
||||
}
|
||||
up_read(&pmd->root_lock);
|
||||
|
||||
return r;
|
||||
@ -1932,8 +1963,11 @@ int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_cou
|
||||
int r = -EINVAL;
|
||||
|
||||
down_write(&pmd->root_lock);
|
||||
if (!pmd->fail_io)
|
||||
if (!pmd->fail_io) {
|
||||
r = __resize_space_map(pmd->metadata_sm, new_count);
|
||||
if (!r)
|
||||
__set_metadata_reserve(pmd);
|
||||
}
|
||||
up_write(&pmd->root_lock);
|
||||
|
||||
return r;
|
||||
|
@ -200,7 +200,13 @@ struct dm_thin_new_mapping;
|
||||
enum pool_mode {
|
||||
PM_WRITE, /* metadata may be changed */
|
||||
PM_OUT_OF_DATA_SPACE, /* metadata may be changed, though data may not be allocated */
|
||||
|
||||
/*
|
||||
* Like READ_ONLY, except may switch back to WRITE on metadata resize. Reported as READ_ONLY.
|
||||
*/
|
||||
PM_OUT_OF_METADATA_SPACE,
|
||||
PM_READ_ONLY, /* metadata may not be changed */
|
||||
|
||||
PM_FAIL, /* all I/O fails */
|
||||
};
|
||||
|
||||
@ -1371,7 +1377,35 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode);
|
||||
|
||||
static void requeue_bios(struct pool *pool);
|
||||
|
||||
static void check_for_space(struct pool *pool)
|
||||
static bool is_read_only_pool_mode(enum pool_mode mode)
|
||||
{
|
||||
return (mode == PM_OUT_OF_METADATA_SPACE || mode == PM_READ_ONLY);
|
||||
}
|
||||
|
||||
static bool is_read_only(struct pool *pool)
|
||||
{
|
||||
return is_read_only_pool_mode(get_pool_mode(pool));
|
||||
}
|
||||
|
||||
static void check_for_metadata_space(struct pool *pool)
|
||||
{
|
||||
int r;
|
||||
const char *ooms_reason = NULL;
|
||||
dm_block_t nr_free;
|
||||
|
||||
r = dm_pool_get_free_metadata_block_count(pool->pmd, &nr_free);
|
||||
if (r)
|
||||
ooms_reason = "Could not get free metadata blocks";
|
||||
else if (!nr_free)
|
||||
ooms_reason = "No free metadata blocks";
|
||||
|
||||
if (ooms_reason && !is_read_only(pool)) {
|
||||
DMERR("%s", ooms_reason);
|
||||
set_pool_mode(pool, PM_OUT_OF_METADATA_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void check_for_data_space(struct pool *pool)
|
||||
{
|
||||
int r;
|
||||
dm_block_t nr_free;
|
||||
@ -1397,14 +1431,16 @@ static int commit(struct pool *pool)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (get_pool_mode(pool) >= PM_READ_ONLY)
|
||||
if (get_pool_mode(pool) >= PM_OUT_OF_METADATA_SPACE)
|
||||
return -EINVAL;
|
||||
|
||||
r = dm_pool_commit_metadata(pool->pmd);
|
||||
if (r)
|
||||
metadata_operation_failed(pool, "dm_pool_commit_metadata", r);
|
||||
else
|
||||
check_for_space(pool);
|
||||
else {
|
||||
check_for_metadata_space(pool);
|
||||
check_for_data_space(pool);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -1470,6 +1506,19 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dm_pool_get_free_metadata_block_count(pool->pmd, &free_blocks);
|
||||
if (r) {
|
||||
metadata_operation_failed(pool, "dm_pool_get_free_metadata_block_count", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!free_blocks) {
|
||||
/* Let's commit before we use up the metadata reserve. */
|
||||
r = commit(pool);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1501,6 +1550,7 @@ static blk_status_t should_error_unserviceable_bio(struct pool *pool)
|
||||
case PM_OUT_OF_DATA_SPACE:
|
||||
return pool->pf.error_if_no_space ? BLK_STS_NOSPC : 0;
|
||||
|
||||
case PM_OUT_OF_METADATA_SPACE:
|
||||
case PM_READ_ONLY:
|
||||
case PM_FAIL:
|
||||
return BLK_STS_IOERR;
|
||||
@ -2464,8 +2514,9 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode)
|
||||
error_retry_list(pool);
|
||||
break;
|
||||
|
||||
case PM_OUT_OF_METADATA_SPACE:
|
||||
case PM_READ_ONLY:
|
||||
if (old_mode != new_mode)
|
||||
if (!is_read_only_pool_mode(old_mode))
|
||||
notify_of_pool_mode_change(pool, "read-only");
|
||||
dm_pool_metadata_read_only(pool->pmd);
|
||||
pool->process_bio = process_bio_read_only;
|
||||
@ -3403,6 +3454,10 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit)
|
||||
DMINFO("%s: growing the metadata device from %llu to %llu blocks",
|
||||
dm_device_name(pool->pool_md),
|
||||
sb_metadata_dev_size, metadata_dev_size);
|
||||
|
||||
if (get_pool_mode(pool) == PM_OUT_OF_METADATA_SPACE)
|
||||
set_pool_mode(pool, PM_WRITE);
|
||||
|
||||
r = dm_pool_resize_metadata_dev(pool->pmd, metadata_dev_size);
|
||||
if (r) {
|
||||
metadata_operation_failed(pool, "dm_pool_resize_metadata_dev", r);
|
||||
@ -3707,7 +3762,7 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv,
|
||||
struct pool_c *pt = ti->private;
|
||||
struct pool *pool = pt->pool;
|
||||
|
||||
if (get_pool_mode(pool) >= PM_READ_ONLY) {
|
||||
if (get_pool_mode(pool) >= PM_OUT_OF_METADATA_SPACE) {
|
||||
DMERR("%s: unable to service pool target messages in READ_ONLY or FAIL mode",
|
||||
dm_device_name(pool->pool_md));
|
||||
return -EOPNOTSUPP;
|
||||
@ -3781,6 +3836,7 @@ static void pool_status(struct dm_target *ti, status_type_t type,
|
||||
dm_block_t nr_blocks_data;
|
||||
dm_block_t nr_blocks_metadata;
|
||||
dm_block_t held_root;
|
||||
enum pool_mode mode;
|
||||
char buf[BDEVNAME_SIZE];
|
||||
char buf2[BDEVNAME_SIZE];
|
||||
struct pool_c *pt = ti->private;
|
||||
@ -3851,9 +3907,10 @@ static void pool_status(struct dm_target *ti, status_type_t type,
|
||||
else
|
||||
DMEMIT("- ");
|
||||
|
||||
if (pool->pf.mode == PM_OUT_OF_DATA_SPACE)
|
||||
mode = get_pool_mode(pool);
|
||||
if (mode == PM_OUT_OF_DATA_SPACE)
|
||||
DMEMIT("out_of_data_space ");
|
||||
else if (pool->pf.mode == PM_READ_ONLY)
|
||||
else if (is_read_only_pool_mode(mode))
|
||||
DMEMIT("ro ");
|
||||
else
|
||||
DMEMIT("rw ");
|
||||
|
@ -99,10 +99,26 @@ static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
|
||||
{
|
||||
struct scatterlist sg;
|
||||
|
||||
sg_init_one(&sg, data, len);
|
||||
ahash_request_set_crypt(req, &sg, NULL, len);
|
||||
|
||||
return crypto_wait_req(crypto_ahash_update(req), wait);
|
||||
if (likely(!is_vmalloc_addr(data))) {
|
||||
sg_init_one(&sg, data, len);
|
||||
ahash_request_set_crypt(req, &sg, NULL, len);
|
||||
return crypto_wait_req(crypto_ahash_update(req), wait);
|
||||
} else {
|
||||
do {
|
||||
int r;
|
||||
size_t this_step = min_t(size_t, len, PAGE_SIZE - offset_in_page(data));
|
||||
flush_kernel_vmap_range((void *)data, this_step);
|
||||
sg_init_table(&sg, 1);
|
||||
sg_set_page(&sg, vmalloc_to_page(data), this_step, offset_in_page(data));
|
||||
ahash_request_set_crypt(req, &sg, NULL, this_step);
|
||||
r = crypto_wait_req(crypto_ahash_update(req), wait);
|
||||
if (unlikely(r))
|
||||
return r;
|
||||
data += this_step;
|
||||
len -= this_step;
|
||||
} while (len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/nospec.h>
|
||||
|
||||
static DEFINE_MUTEX(compass_mutex);
|
||||
|
||||
@ -50,6 +51,7 @@ static int compass_store(struct device *dev, const char *buf, size_t count,
|
||||
return ret;
|
||||
if (val >= strlen(map))
|
||||
return -EINVAL;
|
||||
val = array_index_nospec(val, strlen(map));
|
||||
mutex_lock(&compass_mutex);
|
||||
ret = compass_command(c, map[val]);
|
||||
mutex_unlock(&compass_mutex);
|
||||
|
@ -2131,7 +2131,7 @@ static int ibmvmc_init_crq_queue(struct crq_server_adapter *adapter)
|
||||
retrc = plpar_hcall_norets(H_REG_CRQ,
|
||||
vdev->unit_address,
|
||||
queue->msg_token, PAGE_SIZE);
|
||||
retrc = rc;
|
||||
rc = retrc;
|
||||
|
||||
if (rc == H_RESOURCE)
|
||||
rc = ibmvmc_reset_crq_queue(adapter);
|
||||
|
@ -521,17 +521,15 @@ int mei_cldev_enable(struct mei_cl_device *cldev)
|
||||
|
||||
cl = cldev->cl;
|
||||
|
||||
mutex_lock(&bus->device_lock);
|
||||
if (cl->state == MEI_FILE_UNINITIALIZED) {
|
||||
mutex_lock(&bus->device_lock);
|
||||
ret = mei_cl_link(cl);
|
||||
mutex_unlock(&bus->device_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
/* update pointers */
|
||||
cl->cldev = cldev;
|
||||
}
|
||||
|
||||
mutex_lock(&bus->device_lock);
|
||||
if (mei_cl_is_connected(cl)) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
@ -616,9 +614,8 @@ int mei_cldev_disable(struct mei_cl_device *cldev)
|
||||
if (err < 0)
|
||||
dev_err(bus->dev, "Could not disconnect from the ME client\n");
|
||||
|
||||
out:
|
||||
mei_cl_bus_module_put(cldev);
|
||||
|
||||
out:
|
||||
/* Flush queues and remove any pending read */
|
||||
mei_cl_flush_queues(cl, NULL);
|
||||
mei_cl_unlink(cl);
|
||||
@ -876,12 +873,13 @@ static void mei_cl_bus_dev_release(struct device *dev)
|
||||
|
||||
mei_me_cl_put(cldev->me_cl);
|
||||
mei_dev_bus_put(cldev->bus);
|
||||
mei_cl_unlink(cldev->cl);
|
||||
kfree(cldev->cl);
|
||||
kfree(cldev);
|
||||
}
|
||||
|
||||
static const struct device_type mei_cl_device_type = {
|
||||
.release = mei_cl_bus_dev_release,
|
||||
.release = mei_cl_bus_dev_release,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1767,7 +1767,7 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
rets = buf->size;
|
||||
rets = len;
|
||||
err:
|
||||
cl_dbg(dev, cl, "rpm: autosuspend\n");
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
|
@ -1161,15 +1161,18 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
|
||||
|
||||
props_res = (struct hbm_props_response *)mei_msg;
|
||||
|
||||
if (props_res->status) {
|
||||
if (props_res->status == MEI_HBMS_CLIENT_NOT_FOUND) {
|
||||
dev_dbg(dev->dev, "hbm: properties response: %d CLIENT_NOT_FOUND\n",
|
||||
props_res->me_addr);
|
||||
} else if (props_res->status) {
|
||||
dev_err(dev->dev, "hbm: properties response: wrong status = %d %s\n",
|
||||
props_res->status,
|
||||
mei_hbm_status_str(props_res->status));
|
||||
return -EPROTO;
|
||||
} else {
|
||||
mei_hbm_me_cl_add(dev, props_res);
|
||||
}
|
||||
|
||||
mei_hbm_me_cl_add(dev, props_res);
|
||||
|
||||
/* request property for the next client */
|
||||
if (mei_hbm_prop_req(dev, props_res->me_addr + 1))
|
||||
return -EIO;
|
||||
|
@ -517,19 +517,23 @@ static struct mmc_host_ops meson_mx_mmc_ops = {
|
||||
static struct platform_device *meson_mx_mmc_slot_pdev(struct device *parent)
|
||||
{
|
||||
struct device_node *slot_node;
|
||||
struct platform_device *pdev;
|
||||
|
||||
/*
|
||||
* TODO: the MMC core framework currently does not support
|
||||
* controllers with multiple slots properly. So we only register
|
||||
* the first slot for now
|
||||
*/
|
||||
slot_node = of_find_compatible_node(parent->of_node, NULL, "mmc-slot");
|
||||
slot_node = of_get_compatible_child(parent->of_node, "mmc-slot");
|
||||
if (!slot_node) {
|
||||
dev_warn(parent, "no 'mmc-slot' sub-node found\n");
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
return of_platform_device_create(slot_node, NULL, parent);
|
||||
pdev = of_platform_device_create(slot_node, NULL, parent);
|
||||
of_node_put(slot_node);
|
||||
|
||||
return pdev;
|
||||
}
|
||||
|
||||
static int meson_mx_mmc_add_host(struct meson_mx_mmc_host *host)
|
||||
|
@ -2177,6 +2177,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
|
||||
dma_release_channel(host->tx_chan);
|
||||
dma_release_channel(host->rx_chan);
|
||||
|
||||
dev_pm_clear_wake_irq(host->dev);
|
||||
pm_runtime_dont_use_autosuspend(host->dev);
|
||||
pm_runtime_put_sync(host->dev);
|
||||
pm_runtime_disable(host->dev);
|
||||
|
@ -283,8 +283,12 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
case SIOCFINDIPDDPRT:
|
||||
spin_lock_bh(&ipddp_route_lock);
|
||||
rp = __ipddp_find_route(&rcp);
|
||||
if (rp)
|
||||
memcpy(&rcp2, rp, sizeof(rcp2));
|
||||
if (rp) {
|
||||
memset(&rcp2, 0, sizeof(rcp2));
|
||||
rcp2.ip = rp->ip;
|
||||
rcp2.at = rp->at;
|
||||
rcp2.flags = rp->flags;
|
||||
}
|
||||
spin_unlock_bh(&ipddp_route_lock);
|
||||
|
||||
if (rp) {
|
||||
|
@ -128,7 +128,7 @@
|
||||
#define MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION 0x7000
|
||||
#define MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION BIT(7)
|
||||
#define MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION BIT(6)
|
||||
#define MV88E6XXX_G1_ATU_OP_MISS_VIOLTATION BIT(5)
|
||||
#define MV88E6XXX_G1_ATU_OP_MISS_VIOLATION BIT(5)
|
||||
#define MV88E6XXX_G1_ATU_OP_FULL_VIOLATION BIT(4)
|
||||
|
||||
/* Offset 0x0C: ATU Data Register */
|
||||
|
@ -349,7 +349,7 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
|
||||
chip->ports[entry.portvec].atu_member_violation++;
|
||||
}
|
||||
|
||||
if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) {
|
||||
if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) {
|
||||
dev_err_ratelimited(chip->dev,
|
||||
"ATU miss violation for %pM portvec %x\n",
|
||||
entry.mac, entry.portvec);
|
||||
|
@ -8027,7 +8027,7 @@ static int bnxt_change_mac_addr(struct net_device *dev, void *p)
|
||||
if (ether_addr_equal(addr->sa_data, dev->dev_addr))
|
||||
return 0;
|
||||
|
||||
rc = bnxt_approve_mac(bp, addr->sa_data);
|
||||
rc = bnxt_approve_mac(bp, addr->sa_data, true);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -8827,14 +8827,19 @@ static int bnxt_init_mac_addr(struct bnxt *bp)
|
||||
} else {
|
||||
#ifdef CONFIG_BNXT_SRIOV
|
||||
struct bnxt_vf_info *vf = &bp->vf;
|
||||
bool strict_approval = true;
|
||||
|
||||
if (is_valid_ether_addr(vf->mac_addr)) {
|
||||
/* overwrite netdev dev_addr with admin VF MAC */
|
||||
memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN);
|
||||
/* Older PF driver or firmware may not approve this
|
||||
* correctly.
|
||||
*/
|
||||
strict_approval = false;
|
||||
} else {
|
||||
eth_hw_addr_random(bp->dev);
|
||||
}
|
||||
rc = bnxt_approve_mac(bp, bp->dev->dev_addr);
|
||||
rc = bnxt_approve_mac(bp, bp->dev->dev_addr, strict_approval);
|
||||
#endif
|
||||
}
|
||||
return rc;
|
||||
|
@ -1104,7 +1104,7 @@ update_vf_mac_exit:
|
||||
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||
}
|
||||
|
||||
int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
|
||||
int bnxt_approve_mac(struct bnxt *bp, u8 *mac, bool strict)
|
||||
{
|
||||
struct hwrm_func_vf_cfg_input req = {0};
|
||||
int rc = 0;
|
||||
@ -1122,12 +1122,13 @@ int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
|
||||
memcpy(req.dflt_mac_addr, mac, ETH_ALEN);
|
||||
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
mac_done:
|
||||
if (rc) {
|
||||
if (rc && strict) {
|
||||
rc = -EADDRNOTAVAIL;
|
||||
netdev_warn(bp->dev, "VF MAC address %pM not approved by the PF\n",
|
||||
mac);
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
@ -1144,7 +1145,7 @@ void bnxt_update_vf_mac(struct bnxt *bp)
|
||||
{
|
||||
}
|
||||
|
||||
int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
|
||||
int bnxt_approve_mac(struct bnxt *bp, u8 *mac, bool strict)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -39,5 +39,5 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs);
|
||||
void bnxt_sriov_disable(struct bnxt *);
|
||||
void bnxt_hwrm_exec_fwd_req(struct bnxt *);
|
||||
void bnxt_update_vf_mac(struct bnxt *);
|
||||
int bnxt_approve_mac(struct bnxt *, u8 *);
|
||||
int bnxt_approve_mac(struct bnxt *, u8 *, bool);
|
||||
#endif
|
||||
|
@ -3836,6 +3836,13 @@ static const struct macb_config at91sam9260_config = {
|
||||
.init = macb_init,
|
||||
};
|
||||
|
||||
static const struct macb_config sama5d3macb_config = {
|
||||
.caps = MACB_CAPS_SG_DISABLED
|
||||
| MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
};
|
||||
|
||||
static const struct macb_config pc302gem_config = {
|
||||
.caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE,
|
||||
.dma_burst_length = 16,
|
||||
@ -3903,6 +3910,7 @@ static const struct of_device_id macb_dt_ids[] = {
|
||||
{ .compatible = "cdns,gem", .data = &pc302gem_config },
|
||||
{ .compatible = "atmel,sama5d2-gem", .data = &sama5d2_config },
|
||||
{ .compatible = "atmel,sama5d3-gem", .data = &sama5d3_config },
|
||||
{ .compatible = "atmel,sama5d3-macb", .data = &sama5d3macb_config },
|
||||
{ .compatible = "atmel,sama5d4-gem", .data = &sama5d4_config },
|
||||
{ .compatible = "cdns,at91rm9200-emac", .data = &emac_config },
|
||||
{ .compatible = "cdns,emac", .data = &emac_config },
|
||||
|
@ -2634,7 +2634,7 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
|
||||
/* Wait for link to drop */
|
||||
time = jiffies + (HZ / 10);
|
||||
do {
|
||||
if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
|
||||
if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
|
||||
break;
|
||||
if (!in_interrupt())
|
||||
schedule_timeout_interruptible(1);
|
||||
|
@ -58,6 +58,8 @@ static struct {
|
||||
*/
|
||||
static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
|
||||
const struct phylink_link_state *state);
|
||||
static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode,
|
||||
phy_interface_t interface, struct phy_device *phy);
|
||||
|
||||
/* Queue modes */
|
||||
#define MVPP2_QDIST_SINGLE_MODE 0
|
||||
@ -3142,6 +3144,7 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
|
||||
mvpp22_mode_reconfigure(port);
|
||||
|
||||
if (port->phylink) {
|
||||
netif_carrier_off(port->dev);
|
||||
phylink_start(port->phylink);
|
||||
} else {
|
||||
/* Phylink isn't used as of now for ACPI, so the MAC has to be
|
||||
@ -3150,9 +3153,10 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
|
||||
*/
|
||||
struct phylink_link_state state = {
|
||||
.interface = port->phy_interface,
|
||||
.link = 1,
|
||||
};
|
||||
mvpp2_mac_config(port->dev, MLO_AN_INBAND, &state);
|
||||
mvpp2_mac_link_up(port->dev, MLO_AN_INBAND, port->phy_interface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
netif_tx_start_all_queues(port->dev);
|
||||
@ -4495,10 +4499,6 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
|
||||
return;
|
||||
}
|
||||
|
||||
netif_tx_stop_all_queues(port->dev);
|
||||
if (!port->has_phy)
|
||||
netif_carrier_off(port->dev);
|
||||
|
||||
/* Make sure the port is disabled when reconfiguring the mode */
|
||||
mvpp2_port_disable(port);
|
||||
|
||||
@ -4523,16 +4523,7 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
|
||||
if (port->priv->hw_version == MVPP21 && port->flags & MVPP2_F_LOOPBACK)
|
||||
mvpp2_port_loopback_set(port, state);
|
||||
|
||||
/* If the port already was up, make sure it's still in the same state */
|
||||
if (state->link || !port->has_phy) {
|
||||
mvpp2_port_enable(port);
|
||||
|
||||
mvpp2_egress_enable(port);
|
||||
mvpp2_ingress_enable(port);
|
||||
if (!port->has_phy)
|
||||
netif_carrier_on(dev);
|
||||
netif_tx_wake_all_queues(dev);
|
||||
}
|
||||
mvpp2_port_enable(port);
|
||||
}
|
||||
|
||||
static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode,
|
||||
|
@ -2847,7 +2847,7 @@ static void lan743x_pcidev_shutdown(struct pci_dev *pdev)
|
||||
lan743x_hardware_cleanup(adapter);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static u16 lan743x_pm_wakeframe_crc16(const u8 *buf, int len)
|
||||
{
|
||||
return bitrev16(crc16(0xFFFF, buf, len));
|
||||
@ -3013,7 +3013,7 @@ static int lan743x_pm_resume(struct device *dev)
|
||||
static const struct dev_pm_ops lan743x_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(lan743x_pm_suspend, lan743x_pm_resume)
|
||||
};
|
||||
#endif /*CONFIG_PM */
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static const struct pci_device_id lan743x_pcidev_tbl[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_LAN7430) },
|
||||
@ -3025,7 +3025,7 @@ static struct pci_driver lan743x_pcidev_driver = {
|
||||
.id_table = lan743x_pcidev_tbl,
|
||||
.probe = lan743x_pcidev_probe,
|
||||
.remove = lan743x_pcidev_remove,
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.driver.pm = &lan743x_pm_ops,
|
||||
#endif
|
||||
.shutdown = lan743x_pcidev_shutdown,
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/phy.h>
|
||||
@ -665,6 +666,7 @@ struct rtl8169_private {
|
||||
|
||||
u16 event_slow;
|
||||
const struct rtl_coalesce_info *coalesce_info;
|
||||
struct clk *clk;
|
||||
|
||||
struct mdio_ops {
|
||||
void (*write)(struct rtl8169_private *, int, int);
|
||||
@ -4775,12 +4777,14 @@ static void rtl_pcie_state_l2l3_enable(struct rtl8169_private *tp, bool enable)
|
||||
static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
RTL_W8(tp, Config2, RTL_R8(tp, Config2) | ClkReqEn);
|
||||
RTL_W8(tp, Config5, RTL_R8(tp, Config5) | ASPM_en);
|
||||
RTL_W8(tp, Config2, RTL_R8(tp, Config2) | ClkReqEn);
|
||||
} else {
|
||||
RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~ClkReqEn);
|
||||
RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en);
|
||||
}
|
||||
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
static void rtl_hw_start_8168bb(struct rtl8169_private *tp)
|
||||
@ -5625,6 +5629,8 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
|
||||
|
||||
static void rtl_hw_start_8106(struct rtl8169_private *tp)
|
||||
{
|
||||
rtl_hw_aspm_clkreq_enable(tp, false);
|
||||
|
||||
/* Force LAN exit from ASPM if Rx/Tx are not idle */
|
||||
RTL_W32(tp, FuncEvent, RTL_R32(tp, FuncEvent) | 0x002800);
|
||||
|
||||
@ -5633,6 +5639,7 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp)
|
||||
RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN);
|
||||
|
||||
rtl_pcie_state_l2l3_enable(tp, false);
|
||||
rtl_hw_aspm_clkreq_enable(tp, true);
|
||||
}
|
||||
|
||||
static void rtl_hw_start_8101(struct rtl8169_private *tp)
|
||||
@ -7257,6 +7264,11 @@ static int rtl_jumbo_max(struct rtl8169_private *tp)
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl_disable_clk(void *data)
|
||||
{
|
||||
clk_disable_unprepare(data);
|
||||
}
|
||||
|
||||
static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
|
||||
@ -7277,6 +7289,32 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
|
||||
tp->supports_gmii = cfg->has_gmii;
|
||||
|
||||
/* Get the *optional* external "ether_clk" used on some boards */
|
||||
tp->clk = devm_clk_get(&pdev->dev, "ether_clk");
|
||||
if (IS_ERR(tp->clk)) {
|
||||
rc = PTR_ERR(tp->clk);
|
||||
if (rc == -ENOENT) {
|
||||
/* clk-core allows NULL (for suspend / resume) */
|
||||
tp->clk = NULL;
|
||||
} else if (rc == -EPROBE_DEFER) {
|
||||
return rc;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "failed to get clk: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
rc = clk_prepare_enable(tp->clk);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "failed to enable clk: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = devm_add_action_or_reset(&pdev->dev, rtl_disable_clk,
|
||||
tp->clk);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* enable device (incl. PCI PM wakeup and hotplug setup) */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc < 0) {
|
||||
|
@ -67,7 +67,7 @@ static int dwmac1000_validate_mcast_bins(int mcast_bins)
|
||||
* Description:
|
||||
* This function validates the number of Unicast address entries supported
|
||||
* by a particular Synopsys 10/100/1000 controller. The Synopsys controller
|
||||
* supports 1, 32, 64, or 128 Unicast filter entries for it's Unicast filter
|
||||
* supports 1..32, 64, or 128 Unicast filter entries for it's Unicast filter
|
||||
* logic. This function validates a valid, supported configuration is
|
||||
* selected, and defaults to 1 Unicast address if an unsupported
|
||||
* configuration is selected.
|
||||
@ -77,8 +77,7 @@ static int dwmac1000_validate_ucast_entries(int ucast_entries)
|
||||
int x = ucast_entries;
|
||||
|
||||
switch (x) {
|
||||
case 1:
|
||||
case 32:
|
||||
case 1 ... 32:
|
||||
case 64:
|
||||
case 128:
|
||||
break;
|
||||
|
@ -41,6 +41,7 @@ config TI_DAVINCI_MDIO
|
||||
config TI_DAVINCI_CPDMA
|
||||
tristate "TI DaVinci CPDMA Support"
|
||||
depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || COMPILE_TEST
|
||||
select GENERIC_ALLOCATOR
|
||||
---help---
|
||||
This driver supports TI's DaVinci CPDMA dma engine.
|
||||
|
||||
|
@ -1203,6 +1203,9 @@ static void netvsc_send_vf(struct net_device *ndev,
|
||||
|
||||
net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated;
|
||||
net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial;
|
||||
netdev_info(ndev, "VF slot %u %s\n",
|
||||
net_device_ctx->vf_serial,
|
||||
net_device_ctx->vf_alloc ? "added" : "removed");
|
||||
}
|
||||
|
||||
static void netvsc_receive_inband(struct net_device *ndev,
|
||||
|
@ -1894,20 +1894,6 @@ out_unlock:
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static struct net_device *get_netvsc_bymac(const u8 *mac)
|
||||
{
|
||||
struct net_device_context *ndev_ctx;
|
||||
|
||||
list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
|
||||
struct net_device *dev = hv_get_drvdata(ndev_ctx->device_ctx);
|
||||
|
||||
if (ether_addr_equal(mac, dev->perm_addr))
|
||||
return dev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct net_device *get_netvsc_byref(struct net_device *vf_netdev)
|
||||
{
|
||||
struct net_device_context *net_device_ctx;
|
||||
@ -2036,26 +2022,48 @@ static void netvsc_vf_setup(struct work_struct *w)
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
/* Find netvsc by VMBus serial number.
|
||||
* The PCI hyperv controller records the serial number as the slot.
|
||||
*/
|
||||
static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
|
||||
{
|
||||
struct device *parent = vf_netdev->dev.parent;
|
||||
struct net_device_context *ndev_ctx;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
if (!parent || !dev_is_pci(parent))
|
||||
return NULL; /* not a PCI device */
|
||||
|
||||
pdev = to_pci_dev(parent);
|
||||
if (!pdev->slot) {
|
||||
netdev_notice(vf_netdev, "no PCI slot information\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
|
||||
if (!ndev_ctx->vf_alloc)
|
||||
continue;
|
||||
|
||||
if (ndev_ctx->vf_serial == pdev->slot->number)
|
||||
return hv_get_drvdata(ndev_ctx->device_ctx);
|
||||
}
|
||||
|
||||
netdev_notice(vf_netdev,
|
||||
"no netdev found for slot %u\n", pdev->slot->number);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int netvsc_register_vf(struct net_device *vf_netdev)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
struct net_device_context *net_device_ctx;
|
||||
struct device *pdev = vf_netdev->dev.parent;
|
||||
struct netvsc_device *netvsc_dev;
|
||||
struct net_device *ndev;
|
||||
int ret;
|
||||
|
||||
if (vf_netdev->addr_len != ETH_ALEN)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (!pdev || !dev_is_pci(pdev) || dev_is_pf(pdev))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/*
|
||||
* We will use the MAC address to locate the synthetic interface to
|
||||
* associate with the VF interface. If we don't find a matching
|
||||
* synthetic interface, move on.
|
||||
*/
|
||||
ndev = get_netvsc_bymac(vf_netdev->perm_addr);
|
||||
ndev = get_netvsc_byslot(vf_netdev);
|
||||
if (!ndev)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
@ -2272,17 +2280,15 @@ static int netvsc_remove(struct hv_device *dev)
|
||||
|
||||
cancel_delayed_work_sync(&ndev_ctx->dwork);
|
||||
|
||||
rcu_read_lock();
|
||||
nvdev = rcu_dereference(ndev_ctx->nvdev);
|
||||
|
||||
if (nvdev)
|
||||
rtnl_lock();
|
||||
nvdev = rtnl_dereference(ndev_ctx->nvdev);
|
||||
if (nvdev)
|
||||
cancel_work_sync(&nvdev->subchan_work);
|
||||
|
||||
/*
|
||||
* Call to the vsc driver to let it know that the device is being
|
||||
* removed. Also blocks mtu and channel changes.
|
||||
*/
|
||||
rtnl_lock();
|
||||
vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
|
||||
if (vf_netdev)
|
||||
netvsc_unregister_vf(vf_netdev);
|
||||
@ -2294,7 +2300,6 @@ static int netvsc_remove(struct hv_device *dev)
|
||||
list_del(&ndev_ctx->list);
|
||||
|
||||
rtnl_unlock();
|
||||
rcu_read_unlock();
|
||||
|
||||
hv_set_drvdata(dev, NULL);
|
||||
|
||||
|
@ -429,6 +429,9 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
if (!skb)
|
||||
goto out;
|
||||
|
||||
if (skb_mac_header_len(skb) < ETH_HLEN)
|
||||
goto drop;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
|
||||
goto drop;
|
||||
|
||||
|
@ -1213,13 +1213,13 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
|
||||
{QMI_FIXED_INTF(0x1199, 0x9063, 8)}, /* Sierra Wireless EM7305 */
|
||||
{QMI_FIXED_INTF(0x1199, 0x9063, 10)}, /* Sierra Wireless EM7305 */
|
||||
{QMI_FIXED_INTF(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x9071, 10)}, /* Sierra Wireless MC74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x9079, 8)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x907b, 10)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */
|
||||
{QMI_QUIRK_SET_DTR(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx */
|
||||
{QMI_QUIRK_SET_DTR(0x1199, 0x9071, 10)},/* Sierra Wireless MC74xx */
|
||||
{QMI_QUIRK_SET_DTR(0x1199, 0x9079, 8)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_QUIRK_SET_DTR(0x1199, 0x9079, 10)},/* Sierra Wireless EM74xx */
|
||||
{QMI_QUIRK_SET_DTR(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_QUIRK_SET_DTR(0x1199, 0x907b, 10)},/* Sierra Wireless EM74xx */
|
||||
{QMI_QUIRK_SET_DTR(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */
|
||||
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
|
||||
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
|
||||
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
|
||||
|
@ -478,6 +478,8 @@ static struct sk_buff *veth_xdp_rcv_skb(struct veth_rq *rq, struct sk_buff *skb,
|
||||
int mac_len, delta, off;
|
||||
struct xdp_buff xdp;
|
||||
|
||||
skb_orphan(skb);
|
||||
|
||||
rcu_read_lock();
|
||||
xdp_prog = rcu_dereference(rq->xdp_prog);
|
||||
if (unlikely(!xdp_prog)) {
|
||||
@ -523,8 +525,6 @@ static struct sk_buff *veth_xdp_rcv_skb(struct veth_rq *rq, struct sk_buff *skb,
|
||||
skb_copy_header(nskb, skb);
|
||||
head_off = skb_headroom(nskb) - skb_headroom(skb);
|
||||
skb_headers_offset_update(nskb, head_off);
|
||||
if (skb->sk)
|
||||
skb_set_owner_w(nskb, skb->sk);
|
||||
consume_skb(skb);
|
||||
skb = nskb;
|
||||
}
|
||||
|
@ -908,7 +908,11 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
|
||||
BUG_ON(pull_to <= skb_headlen(skb));
|
||||
__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
|
||||
}
|
||||
BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS);
|
||||
if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
|
||||
queue->rx.rsp_cons = ++cons;
|
||||
kfree_skb(nskb);
|
||||
return ~0U;
|
||||
}
|
||||
|
||||
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
|
||||
skb_frag_page(nfrag),
|
||||
@ -1045,6 +1049,8 @@ err:
|
||||
skb->len += rx->status;
|
||||
|
||||
i = xennet_fill_frags(queue, skb, &tmpq);
|
||||
if (unlikely(i == ~0U))
|
||||
goto err;
|
||||
|
||||
if (rx->flags & XEN_NETRXF_csum_blank)
|
||||
skb->ip_summed = CHECKSUM_PARTIAL;
|
||||
|
@ -66,6 +66,7 @@ struct nvmet_rdma_rsp {
|
||||
|
||||
struct nvmet_req req;
|
||||
|
||||
bool allocated;
|
||||
u8 n_rdma;
|
||||
u32 flags;
|
||||
u32 invalidate_rkey;
|
||||
@ -174,11 +175,19 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&queue->rsps_lock, flags);
|
||||
rsp = list_first_entry(&queue->free_rsps,
|
||||
rsp = list_first_entry_or_null(&queue->free_rsps,
|
||||
struct nvmet_rdma_rsp, free_list);
|
||||
list_del(&rsp->free_list);
|
||||
if (likely(rsp))
|
||||
list_del(&rsp->free_list);
|
||||
spin_unlock_irqrestore(&queue->rsps_lock, flags);
|
||||
|
||||
if (unlikely(!rsp)) {
|
||||
rsp = kmalloc(sizeof(*rsp), GFP_KERNEL);
|
||||
if (unlikely(!rsp))
|
||||
return NULL;
|
||||
rsp->allocated = true;
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
@ -187,6 +196,11 @@ nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (rsp->allocated) {
|
||||
kfree(rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&rsp->queue->rsps_lock, flags);
|
||||
list_add_tail(&rsp->free_list, &rsp->queue->free_rsps);
|
||||
spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags);
|
||||
@ -776,6 +790,15 @@ static void nvmet_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||
|
||||
cmd->queue = queue;
|
||||
rsp = nvmet_rdma_get_rsp(queue);
|
||||
if (unlikely(!rsp)) {
|
||||
/*
|
||||
* we get here only under memory pressure,
|
||||
* silently drop and have the host retry
|
||||
* as we can't even fail it.
|
||||
*/
|
||||
nvmet_rdma_post_recv(queue->dev, cmd);
|
||||
return;
|
||||
}
|
||||
rsp->queue = queue;
|
||||
rsp->cmd = cmd;
|
||||
rsp->flags = 0;
|
||||
|
@ -140,6 +140,9 @@ void of_populate_phandle_cache(void)
|
||||
if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
|
||||
phandles++;
|
||||
|
||||
if (!phandles)
|
||||
goto out;
|
||||
|
||||
cache_entries = roundup_pow_of_two(phandles);
|
||||
phandle_cache_mask = cache_entries - 1;
|
||||
|
||||
|
@ -89,6 +89,9 @@ static enum pci_protocol_version_t pci_protocol_version;
|
||||
|
||||
#define STATUS_REVISION_MISMATCH 0xC0000059
|
||||
|
||||
/* space for 32bit serial number as string */
|
||||
#define SLOT_NAME_SIZE 11
|
||||
|
||||
/*
|
||||
* Message Types
|
||||
*/
|
||||
@ -494,6 +497,7 @@ struct hv_pci_dev {
|
||||
struct list_head list_entry;
|
||||
refcount_t refs;
|
||||
enum hv_pcichild_state state;
|
||||
struct pci_slot *pci_slot;
|
||||
struct pci_function_description desc;
|
||||
bool reported_missing;
|
||||
struct hv_pcibus_device *hbus;
|
||||
@ -1457,6 +1461,34 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus)
|
||||
spin_unlock_irqrestore(&hbus->device_list_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assign entries in sysfs pci slot directory.
|
||||
*
|
||||
* Note that this function does not need to lock the children list
|
||||
* because it is called from pci_devices_present_work which
|
||||
* is serialized with hv_eject_device_work because they are on the
|
||||
* same ordered workqueue. Therefore hbus->children list will not change
|
||||
* even when pci_create_slot sleeps.
|
||||
*/
|
||||
static void hv_pci_assign_slots(struct hv_pcibus_device *hbus)
|
||||
{
|
||||
struct hv_pci_dev *hpdev;
|
||||
char name[SLOT_NAME_SIZE];
|
||||
int slot_nr;
|
||||
|
||||
list_for_each_entry(hpdev, &hbus->children, list_entry) {
|
||||
if (hpdev->pci_slot)
|
||||
continue;
|
||||
|
||||
slot_nr = PCI_SLOT(wslot_to_devfn(hpdev->desc.win_slot.slot));
|
||||
snprintf(name, SLOT_NAME_SIZE, "%u", hpdev->desc.ser);
|
||||
hpdev->pci_slot = pci_create_slot(hbus->pci_bus, slot_nr,
|
||||
name, NULL);
|
||||
if (!hpdev->pci_slot)
|
||||
pr_warn("pci_create slot %s failed\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create_root_hv_pci_bus() - Expose a new root PCI bus
|
||||
* @hbus: Root PCI bus, as understood by this driver
|
||||
@ -1480,6 +1512,7 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus)
|
||||
pci_lock_rescan_remove();
|
||||
pci_scan_child_bus(hbus->pci_bus);
|
||||
pci_bus_assign_resources(hbus->pci_bus);
|
||||
hv_pci_assign_slots(hbus);
|
||||
pci_bus_add_devices(hbus->pci_bus);
|
||||
pci_unlock_rescan_remove();
|
||||
hbus->state = hv_pcibus_installed;
|
||||
@ -1742,6 +1775,7 @@ static void pci_devices_present_work(struct work_struct *work)
|
||||
*/
|
||||
pci_lock_rescan_remove();
|
||||
pci_scan_child_bus(hbus->pci_bus);
|
||||
hv_pci_assign_slots(hbus);
|
||||
pci_unlock_rescan_remove();
|
||||
break;
|
||||
|
||||
@ -1858,6 +1892,9 @@ static void hv_eject_device_work(struct work_struct *work)
|
||||
list_del(&hpdev->list_entry);
|
||||
spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags);
|
||||
|
||||
if (hpdev->pci_slot)
|
||||
pci_destroy_slot(hpdev->pci_slot);
|
||||
|
||||
memset(&ctxt, 0, sizeof(ctxt));
|
||||
ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message;
|
||||
ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE;
|
||||
|
@ -496,7 +496,7 @@ int pciehp_power_on_slot(struct slot *slot)
|
||||
u16 slot_status;
|
||||
int retval;
|
||||
|
||||
/* Clear sticky power-fault bit from previous power failures */
|
||||
/* Clear power-fault bit from previous power failures */
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
|
||||
if (slot_status & PCI_EXP_SLTSTA_PFD)
|
||||
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
|
||||
@ -646,6 +646,14 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
|
||||
pciehp_handle_button_press(slot);
|
||||
}
|
||||
|
||||
/* Check Power Fault Detected */
|
||||
if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
|
||||
ctrl->power_fault_detected = 1;
|
||||
ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot));
|
||||
pciehp_set_attention_status(slot, 1);
|
||||
pciehp_green_led_off(slot);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable requests have higher priority than Presence Detect Changed
|
||||
* or Data Link Layer State Changed events.
|
||||
@ -657,14 +665,6 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
|
||||
pciehp_handle_presence_or_link_change(slot, events);
|
||||
up_read(&ctrl->reset_lock);
|
||||
|
||||
/* Check Power Fault Detected */
|
||||
if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
|
||||
ctrl->power_fault_detected = 1;
|
||||
ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(slot));
|
||||
pciehp_set_attention_status(slot, 1);
|
||||
pciehp_green_led_off(slot);
|
||||
}
|
||||
|
||||
pci_config_pm_runtime_put(pdev);
|
||||
wake_up(&ctrl->requester);
|
||||
return IRQ_HANDLED;
|
||||
|
@ -4547,6 +4547,7 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev)
|
||||
|
||||
return pci_dev_wait(dev, "bus reset", PCIE_RESET_READY_POLL_MS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset);
|
||||
|
||||
static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
|
||||
{
|
||||
@ -5200,7 +5201,7 @@ static int __pci_reset_bus(struct pci_bus *bus)
|
||||
*/
|
||||
int pci_reset_bus(struct pci_dev *pdev)
|
||||
{
|
||||
return pci_probe_reset_slot(pdev->slot) ?
|
||||
return (!pci_probe_reset_slot(pdev->slot)) ?
|
||||
__pci_reset_slot(pdev->slot) : __pci_reset_bus(pdev->bus);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_reset_bus);
|
||||
|
@ -2074,6 +2074,7 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev)
|
||||
{
|
||||
#ifdef CONFIG_PCI_PASID
|
||||
struct pci_dev *bridge;
|
||||
int pcie_type;
|
||||
u32 cap;
|
||||
|
||||
if (!pci_is_pcie(dev))
|
||||
@ -2083,7 +2084,9 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev)
|
||||
if (!(cap & PCI_EXP_DEVCAP2_EE_PREFIX))
|
||||
return;
|
||||
|
||||
if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
|
||||
pcie_type = pci_pcie_type(dev);
|
||||
if (pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pcie_type == PCI_EXP_TYPE_RC_END)
|
||||
dev->eetlp_prefix_path = 1;
|
||||
else {
|
||||
bridge = pci_upstream_bridge(dev);
|
||||
|
@ -4355,11 +4355,6 @@ static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags)
|
||||
*
|
||||
* 0x9d10-0x9d1b PCI Express Root port #{1-12}
|
||||
*
|
||||
* The 300 series chipset suffers from the same bug so include those root
|
||||
* ports here as well.
|
||||
*
|
||||
* 0xa32c-0xa343 PCI Express Root port #{0-24}
|
||||
*
|
||||
* [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html
|
||||
* [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html
|
||||
* [3] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-spec-update.html
|
||||
@ -4377,7 +4372,6 @@ static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev)
|
||||
case 0xa110 ... 0xa11f: case 0xa167 ... 0xa16a: /* Sunrise Point */
|
||||
case 0xa290 ... 0xa29f: case 0xa2e7 ... 0xa2ee: /* Union Point */
|
||||
case 0x9d10 ... 0x9d1b: /* 7th & 8th Gen Mobile */
|
||||
case 0xa32c ... 0xa343: /* 300 series */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include <linux/poll.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <linux/nospec.h>
|
||||
|
||||
MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver");
|
||||
MODULE_VERSION("0.1");
|
||||
MODULE_LICENSE("GPL");
|
||||
@ -909,6 +911,8 @@ static int ioctl_port_to_pff(struct switchtec_dev *stdev,
|
||||
default:
|
||||
if (p.port > ARRAY_SIZE(pcfg->dsp_pff_inst_id))
|
||||
return -EINVAL;
|
||||
p.port = array_index_nospec(p.port,
|
||||
ARRAY_SIZE(pcfg->dsp_pff_inst_id) + 1);
|
||||
p.pff = ioread32(&pcfg->dsp_pff_inst_id[p.port - 1]);
|
||||
break;
|
||||
}
|
||||
|
@ -1040,7 +1040,7 @@ static int madera_pin_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* if the configuration is provided through pdata, apply it */
|
||||
if (pdata) {
|
||||
if (pdata && pdata->gpio_configs) {
|
||||
ret = pinctrl_register_mappings(pdata->gpio_configs,
|
||||
pdata->n_gpio_configs);
|
||||
if (ret) {
|
||||
|
@ -793,7 +793,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
|
||||
|
||||
err = pinctrl_generic_add_group(jzpc->pctl, group->name,
|
||||
group->pins, group->num_pins, group->data);
|
||||
if (err) {
|
||||
if (err < 0) {
|
||||
dev_err(dev, "Failed to register group %s\n",
|
||||
group->name);
|
||||
return err;
|
||||
@ -806,7 +806,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
|
||||
err = pinmux_generic_add_function(jzpc->pctl, func->name,
|
||||
func->group_names, func->num_group_names,
|
||||
func->data);
|
||||
if (err) {
|
||||
if (err < 0) {
|
||||
dev_err(dev, "Failed to register function %s\n",
|
||||
func->name);
|
||||
return err;
|
||||
|
@ -634,6 +634,29 @@ static void msm_gpio_irq_mask(struct irq_data *d)
|
||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||
|
||||
val = readl(pctrl->regs + g->intr_cfg_reg);
|
||||
/*
|
||||
* There are two bits that control interrupt forwarding to the CPU. The
|
||||
* RAW_STATUS_EN bit causes the level or edge sensed on the line to be
|
||||
* latched into the interrupt status register when the hardware detects
|
||||
* an irq that it's configured for (either edge for edge type or level
|
||||
* for level type irq). The 'non-raw' status enable bit causes the
|
||||
* hardware to assert the summary interrupt to the CPU if the latched
|
||||
* status bit is set. There's a bug though, the edge detection logic
|
||||
* seems to have a problem where toggling the RAW_STATUS_EN bit may
|
||||
* cause the status bit to latch spuriously when there isn't any edge
|
||||
* so we can't touch that bit for edge type irqs and we have to keep
|
||||
* the bit set anyway so that edges are latched while the line is masked.
|
||||
*
|
||||
* To make matters more complicated, leaving the RAW_STATUS_EN bit
|
||||
* enabled all the time causes level interrupts to re-latch into the
|
||||
* status register because the level is still present on the line after
|
||||
* we ack it. We clear the raw status enable bit during mask here and
|
||||
* set the bit on unmask so the interrupt can't latch into the hardware
|
||||
* while it's masked.
|
||||
*/
|
||||
if (irqd_get_trigger_type(d) & IRQ_TYPE_LEVEL_MASK)
|
||||
val &= ~BIT(g->intr_raw_status_bit);
|
||||
|
||||
val &= ~BIT(g->intr_enable_bit);
|
||||
writel(val, pctrl->regs + g->intr_cfg_reg);
|
||||
|
||||
@ -655,6 +678,7 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
|
||||
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||
|
||||
val = readl(pctrl->regs + g->intr_cfg_reg);
|
||||
val |= BIT(g->intr_raw_status_bit);
|
||||
val |= BIT(g->intr_enable_bit);
|
||||
writel(val, pctrl->regs + g->intr_cfg_reg);
|
||||
|
||||
|
@ -872,8 +872,6 @@ static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
|
||||
if (bits & 0x07)
|
||||
return -EINVAL;
|
||||
|
||||
memset(bitmap, 0, bits / 8);
|
||||
|
||||
if (str[0] == '0' && str[1] == 'x')
|
||||
str++;
|
||||
if (*str == 'x')
|
||||
@ -895,25 +893,23 @@ static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
|
||||
}
|
||||
|
||||
/*
|
||||
* str2clrsetmasks() - parse bitmask argument and set the clear and
|
||||
* the set bitmap mask. A concatenation (done with ',') of these terms
|
||||
* is recognized:
|
||||
* modify_bitmap() - parse bitmask argument and modify an existing
|
||||
* bit mask accordingly. A concatenation (done with ',') of these
|
||||
* terms is recognized:
|
||||
* +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]
|
||||
* <bitnr> may be any valid number (hex, decimal or octal) in the range
|
||||
* 0...bits-1; the leading + or - is required. Here are some examples:
|
||||
* +0-15,+32,-128,-0xFF
|
||||
* -0-255,+1-16,+0x128
|
||||
* +1,+2,+3,+4,-5,-7-10
|
||||
* Returns a clear and a set bitmask. Every positive value in the string
|
||||
* results in a bit set in the set mask and every negative value in the
|
||||
* string results in a bit SET in the clear mask. As a bit may be touched
|
||||
* more than once, the last 'operation' wins: +0-255,-128 = all but bit
|
||||
* 128 set in the set mask, only bit 128 set in the clear mask.
|
||||
* Returns the new bitmap after all changes have been applied. Every
|
||||
* positive value in the string will set a bit and every negative value
|
||||
* in the string will clear a bit. As a bit may be touched more than once,
|
||||
* the last 'operation' wins:
|
||||
* +0-255,-128 = first bits 0-255 will be set, then bit 128 will be
|
||||
* cleared again. All other bits are unmodified.
|
||||
*/
|
||||
static int str2clrsetmasks(const char *str,
|
||||
unsigned long *clrmap,
|
||||
unsigned long *setmap,
|
||||
int bits)
|
||||
static int modify_bitmap(const char *str, unsigned long *bitmap, int bits)
|
||||
{
|
||||
int a, i, z;
|
||||
char *np, sign;
|
||||
@ -922,9 +918,6 @@ static int str2clrsetmasks(const char *str,
|
||||
if (bits & 0x07)
|
||||
return -EINVAL;
|
||||
|
||||
memset(clrmap, 0, bits / 8);
|
||||
memset(setmap, 0, bits / 8);
|
||||
|
||||
while (*str) {
|
||||
sign = *str++;
|
||||
if (sign != '+' && sign != '-')
|
||||
@ -940,13 +933,10 @@ static int str2clrsetmasks(const char *str,
|
||||
str = np;
|
||||
}
|
||||
for (i = a; i <= z; i++)
|
||||
if (sign == '+') {
|
||||
set_bit_inv(i, setmap);
|
||||
clear_bit_inv(i, clrmap);
|
||||
} else {
|
||||
clear_bit_inv(i, setmap);
|
||||
set_bit_inv(i, clrmap);
|
||||
}
|
||||
if (sign == '+')
|
||||
set_bit_inv(i, bitmap);
|
||||
else
|
||||
clear_bit_inv(i, bitmap);
|
||||
while (*str == ',' || *str == '\n')
|
||||
str++;
|
||||
}
|
||||
@ -970,44 +960,34 @@ static int process_mask_arg(const char *str,
|
||||
unsigned long *bitmap, int bits,
|
||||
struct mutex *lock)
|
||||
{
|
||||
int i;
|
||||
unsigned long *newmap, size;
|
||||
int rc;
|
||||
|
||||
/* bits needs to be a multiple of 8 */
|
||||
if (bits & 0x07)
|
||||
return -EINVAL;
|
||||
|
||||
if (*str == '+' || *str == '-') {
|
||||
DECLARE_BITMAP(clrm, bits);
|
||||
DECLARE_BITMAP(setm, bits);
|
||||
|
||||
i = str2clrsetmasks(str, clrm, setm, bits);
|
||||
if (i)
|
||||
return i;
|
||||
if (mutex_lock_interruptible(lock))
|
||||
return -ERESTARTSYS;
|
||||
for (i = 0; i < bits; i++) {
|
||||
if (test_bit_inv(i, clrm))
|
||||
clear_bit_inv(i, bitmap);
|
||||
if (test_bit_inv(i, setm))
|
||||
set_bit_inv(i, bitmap);
|
||||
}
|
||||
} else {
|
||||
DECLARE_BITMAP(setm, bits);
|
||||
|
||||
i = hex2bitmap(str, setm, bits);
|
||||
if (i)
|
||||
return i;
|
||||
if (mutex_lock_interruptible(lock))
|
||||
return -ERESTARTSYS;
|
||||
for (i = 0; i < bits; i++)
|
||||
if (test_bit_inv(i, setm))
|
||||
set_bit_inv(i, bitmap);
|
||||
else
|
||||
clear_bit_inv(i, bitmap);
|
||||
size = BITS_TO_LONGS(bits)*sizeof(unsigned long);
|
||||
newmap = kmalloc(size, GFP_KERNEL);
|
||||
if (!newmap)
|
||||
return -ENOMEM;
|
||||
if (mutex_lock_interruptible(lock)) {
|
||||
kfree(newmap);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
mutex_unlock(lock);
|
||||
|
||||
return 0;
|
||||
if (*str == '+' || *str == '-') {
|
||||
memcpy(newmap, bitmap, size);
|
||||
rc = modify_bitmap(str, newmap, bits);
|
||||
} else {
|
||||
memset(newmap, 0, size);
|
||||
rc = hex2bitmap(str, newmap, bits);
|
||||
}
|
||||
if (rc == 0)
|
||||
memcpy(bitmap, newmap, size);
|
||||
mutex_unlock(lock);
|
||||
kfree(newmap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -30,7 +30,11 @@
|
||||
|
||||
#define DRIVER_NAME "fsl-dspi"
|
||||
|
||||
#ifdef CONFIG_M5441x
|
||||
#define DSPI_FIFO_SIZE 16
|
||||
#else
|
||||
#define DSPI_FIFO_SIZE 4
|
||||
#endif
|
||||
#define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024)
|
||||
|
||||
#define SPI_MCR 0x00
|
||||
@ -623,9 +627,11 @@ static void dspi_tcfq_read(struct fsl_dspi *dspi)
|
||||
static void dspi_eoq_write(struct fsl_dspi *dspi)
|
||||
{
|
||||
int fifo_size = DSPI_FIFO_SIZE;
|
||||
u16 xfer_cmd = dspi->tx_cmd;
|
||||
|
||||
/* Fill TX FIFO with as many transfers as possible */
|
||||
while (dspi->len && fifo_size--) {
|
||||
dspi->tx_cmd = xfer_cmd;
|
||||
/* Request EOQF for last transfer in FIFO */
|
||||
if (dspi->len == dspi->bytes_per_word || fifo_size == 0)
|
||||
dspi->tx_cmd |= SPI_PUSHR_CMD_EOQ;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user