Merge remote-tracking branch 'common/android-4.9' into hikey-4.9
Change-Id: Ib72a79566fc44bd93c2901b60daa16242ecb4053
This commit is contained in:
@@ -436,6 +436,8 @@ sysrq.txt
|
||||
- info on the magic SysRq key.
|
||||
target/
|
||||
- directory with info on generating TCM v4 fabric .ko modules
|
||||
tee.txt
|
||||
- info on the TEE subsystem and drivers
|
||||
this_cpu_ops.txt
|
||||
- List rationale behind and the way to use this_cpu operations.
|
||||
thermal/
|
||||
|
||||
@@ -51,6 +51,18 @@ Description:
|
||||
Controls the dirty page count condition for the in-place-update
|
||||
policies.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/min_hot_blocks
|
||||
Date: March 2017
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description:
|
||||
Controls the dirty page count condition for redefining hot data.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/min_ssr_sections
|
||||
Date: October 2017
|
||||
Contact: "Chao Yu" <yuchao0@huawei.com>
|
||||
Description:
|
||||
Controls the fee section threshold to trigger SSR allocation.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/max_small_discards
|
||||
Date: November 2013
|
||||
Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||
@@ -102,6 +114,12 @@ Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description:
|
||||
Controls the idle timing.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/iostat_enable
|
||||
Date: August 2017
|
||||
Contact: "Chao Yu" <yuchao0@huawei.com>
|
||||
Description:
|
||||
Controls to enable/disable IO stat.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/ra_nid_pages
|
||||
Date: October 2015
|
||||
Contact: "Chao Yu" <chao2.yu@samsung.com>
|
||||
@@ -122,6 +140,12 @@ Contact: "Shuoran Liu" <liushuoran@huawei.com>
|
||||
Description:
|
||||
Shows total written kbytes issued to disk.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/feature
|
||||
Date: July 2017
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description:
|
||||
Shows all enabled features in current device.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/inject_rate
|
||||
Date: May 2016
|
||||
Contact: "Sheng Yong" <shengyong1@huawei.com>
|
||||
@@ -138,7 +162,18 @@ What: /sys/fs/f2fs/<disk>/reserved_blocks
|
||||
Date: June 2017
|
||||
Contact: "Chao Yu" <yuchao0@huawei.com>
|
||||
Description:
|
||||
Controls current reserved blocks in system.
|
||||
Controls target reserved blocks in system, the threshold
|
||||
is soft, it could exceed current available user space.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/current_reserved_blocks
|
||||
Date: October 2017
|
||||
Contact: "Yunlong Song" <yunlong.song@huawei.com>
|
||||
Contact: "Chao Yu" <yuchao0@huawei.com>
|
||||
Description:
|
||||
Shows current reserved blocks in system, it may be temporarily
|
||||
smaller than target_reserved_blocks, but will gradually
|
||||
increase to target_reserved_blocks when more free blocks are
|
||||
freed by user later.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/gc_urgent
|
||||
Date: August 2017
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
OP-TEE Device Tree Bindings
|
||||
|
||||
OP-TEE is a piece of software using hardware features to provide a Trusted
|
||||
Execution Environment. The security can be provided with ARM TrustZone, but
|
||||
also by virtualization or a separate chip.
|
||||
|
||||
We're using "linaro" as the first part of the compatible property for
|
||||
the reference implementation maintained by Linaro.
|
||||
|
||||
* OP-TEE based on ARM TrustZone required properties:
|
||||
|
||||
- compatible : should contain "linaro,optee-tz"
|
||||
|
||||
- method : The method of calling the OP-TEE Trusted OS. Permitted
|
||||
values are:
|
||||
|
||||
"smc" : SMC #0, with the register assignments specified
|
||||
in drivers/tee/optee/optee_smc.h
|
||||
|
||||
"hvc" : HVC #0, with the register assignments specified
|
||||
in drivers/tee/optee/optee_smc.h
|
||||
|
||||
|
||||
|
||||
Example:
|
||||
firmware {
|
||||
optee {
|
||||
compatible = "linaro,optee-tz";
|
||||
method = "smc";
|
||||
};
|
||||
};
|
||||
@@ -34,6 +34,10 @@ Required properties:
|
||||
|
||||
- reg: I2C address
|
||||
|
||||
Optional properties:
|
||||
- smbus-timeout-disable: When set, the smbus timeout function will be disabled.
|
||||
This is not supported on all chips.
|
||||
|
||||
Example:
|
||||
|
||||
temp-sensor@1a {
|
||||
|
||||
@@ -156,6 +156,7 @@ lacie LaCie
|
||||
lantiq Lantiq Semiconductor
|
||||
lenovo Lenovo Group Ltd.
|
||||
lg LG Corporation
|
||||
linaro Linaro Limited
|
||||
linux Linux-specific binding
|
||||
lltc Linear Technology Corporation
|
||||
lsi LSI Corp. (LSI Logic)
|
||||
|
||||
@@ -308,6 +308,7 @@ Code Seq#(hex) Include File Comments
|
||||
0xA3 80-8F Port ACL in development:
|
||||
<mailto:tlewis@mindspring.com>
|
||||
0xA3 90-9F linux/dtlk.h
|
||||
0xA4 00-1F uapi/linux/tee.h Generic TEE subsystem
|
||||
0xAA 00-3F linux/uapi/linux/userfaultfd.h
|
||||
0xAB 00-1F linux/nbd.h
|
||||
0xAC 00-1F linux/raw.h
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
TEE subsystem
|
||||
This document describes the TEE subsystem in Linux.
|
||||
|
||||
A TEE (Trusted Execution Environment) is a trusted OS running in some
|
||||
secure environment, for example, TrustZone on ARM CPUs, or a separate
|
||||
secure co-processor etc. A TEE driver handles the details needed to
|
||||
communicate with the TEE.
|
||||
|
||||
This subsystem deals with:
|
||||
|
||||
- Registration of TEE drivers
|
||||
|
||||
- Managing shared memory between Linux and the TEE
|
||||
|
||||
- Providing a generic API to the TEE
|
||||
|
||||
The TEE interface
|
||||
=================
|
||||
|
||||
include/uapi/linux/tee.h defines the generic interface to a TEE.
|
||||
|
||||
User space (the client) connects to the driver by opening /dev/tee[0-9]* or
|
||||
/dev/teepriv[0-9]*.
|
||||
|
||||
- TEE_IOC_SHM_ALLOC allocates shared memory and returns a file descriptor
|
||||
which user space can mmap. When user space doesn't need the file
|
||||
descriptor any more, it should be closed. When shared memory isn't needed
|
||||
any longer it should be unmapped with munmap() to allow the reuse of
|
||||
memory.
|
||||
|
||||
- TEE_IOC_VERSION lets user space know which TEE this driver handles and
|
||||
the its capabilities.
|
||||
|
||||
- TEE_IOC_OPEN_SESSION opens a new session to a Trusted Application.
|
||||
|
||||
- TEE_IOC_INVOKE invokes a function in a Trusted Application.
|
||||
|
||||
- TEE_IOC_CANCEL may cancel an ongoing TEE_IOC_OPEN_SESSION or TEE_IOC_INVOKE.
|
||||
|
||||
- TEE_IOC_CLOSE_SESSION closes a session to a Trusted Application.
|
||||
|
||||
There are two classes of clients, normal clients and supplicants. The latter is
|
||||
a helper process for the TEE to access resources in Linux, for example file
|
||||
system access. A normal client opens /dev/tee[0-9]* and a supplicant opens
|
||||
/dev/teepriv[0-9].
|
||||
|
||||
Much of the communication between clients and the TEE is opaque to the
|
||||
driver. The main job for the driver is to receive requests from the
|
||||
clients, forward them to the TEE and send back the results. In the case of
|
||||
supplicants the communication goes in the other direction, the TEE sends
|
||||
requests to the supplicant which then sends back the result.
|
||||
|
||||
OP-TEE driver
|
||||
=============
|
||||
|
||||
The OP-TEE driver handles OP-TEE [1] based TEEs. Currently it is only the ARM
|
||||
TrustZone based OP-TEE solution that is supported.
|
||||
|
||||
Lowest level of communication with OP-TEE builds on ARM SMC Calling
|
||||
Convention (SMCCC) [2], which is the foundation for OP-TEE's SMC interface
|
||||
[3] used internally by the driver. Stacked on top of that is OP-TEE Message
|
||||
Protocol [4].
|
||||
|
||||
OP-TEE SMC interface provides the basic functions required by SMCCC and some
|
||||
additional functions specific for OP-TEE. The most interesting functions are:
|
||||
|
||||
- OPTEE_SMC_FUNCID_CALLS_UID (part of SMCCC) returns the version information
|
||||
which is then returned by TEE_IOC_VERSION
|
||||
|
||||
- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
|
||||
to tell, for instance, a TrustZone OP-TEE apart from an OP-TEE running on a
|
||||
separate secure co-processor.
|
||||
|
||||
- OPTEE_SMC_CALL_WITH_ARG drives the OP-TEE message protocol
|
||||
|
||||
- OPTEE_SMC_GET_SHM_CONFIG lets the driver and OP-TEE agree on which memory
|
||||
range to used for shared memory between Linux and OP-TEE.
|
||||
|
||||
The GlobalPlatform TEE Client API [5] is implemented on top of the generic
|
||||
TEE API.
|
||||
|
||||
Picture of the relationship between the different components in the
|
||||
OP-TEE architecture.
|
||||
|
||||
User space Kernel Secure world
|
||||
~~~~~~~~~~ ~~~~~~ ~~~~~~~~~~~~
|
||||
+--------+ +-------------+
|
||||
| Client | | Trusted |
|
||||
+--------+ | Application |
|
||||
/\ +-------------+
|
||||
|| +----------+ /\
|
||||
|| |tee- | ||
|
||||
|| |supplicant| \/
|
||||
|| +----------+ +-------------+
|
||||
\/ /\ | TEE Internal|
|
||||
+-------+ || | API |
|
||||
+ TEE | || +--------+--------+ +-------------+
|
||||
| Client| || | TEE | OP-TEE | | OP-TEE |
|
||||
| API | \/ | subsys | driver | | Trusted OS |
|
||||
+-------+----------------+----+-------+----+-----------+-------------+
|
||||
| Generic TEE API | | OP-TEE MSG |
|
||||
| IOCTL (TEE_IOC_*) | | SMCCC (OPTEE_SMC_CALL_*) |
|
||||
+-----------------------------+ +------------------------------+
|
||||
|
||||
RPC (Remote Procedure Call) are requests from secure world to kernel driver
|
||||
or tee-supplicant. An RPC is identified by a special range of SMCCC return
|
||||
values from OPTEE_SMC_CALL_WITH_ARG. RPC messages which are intended for the
|
||||
kernel are handled by the kernel driver. Other RPC messages will be forwarded to
|
||||
tee-supplicant without further involvement of the driver, except switching
|
||||
shared memory buffer representation.
|
||||
|
||||
References:
|
||||
[1] https://github.com/OP-TEE/optee_os
|
||||
[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
|
||||
[3] drivers/tee/optee/optee_smc.h
|
||||
[4] drivers/tee/optee/optee_msg.h
|
||||
[5] http://www.globalplatform.org/specificationsdevice.asp look for
|
||||
"TEE Client API Specification v1.0" and click download.
|
||||
+13
@@ -9010,6 +9010,11 @@ F: arch/*/oprofile/
|
||||
F: drivers/oprofile/
|
||||
F: include/linux/oprofile.h
|
||||
|
||||
OP-TEE DRIVER
|
||||
M: Jens Wiklander <jens.wiklander@linaro.org>
|
||||
S: Maintained
|
||||
F: drivers/tee/optee/
|
||||
|
||||
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
|
||||
M: Mark Fasheh <mfasheh@versity.com>
|
||||
M: Joel Becker <jlbec@evilplan.org>
|
||||
@@ -10663,6 +10668,14 @@ F: drivers/hwtracing/stm/
|
||||
F: include/linux/stm.h
|
||||
F: include/uapi/linux/stm.h
|
||||
|
||||
TEE SUBSYSTEM
|
||||
M: Jens Wiklander <jens.wiklander@linaro.org>
|
||||
S: Maintained
|
||||
F: include/linux/tee_drv.h
|
||||
F: include/uapi/linux/tee.h
|
||||
F: drivers/tee/
|
||||
F: Documentation/tee.txt
|
||||
|
||||
THUNDERBOLT DRIVER
|
||||
M: Andreas Noever <andreas.noever@gmail.com>
|
||||
S: Maintained
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 65
|
||||
SUBLEVEL = 67
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc1_pins &mmc1_cd>;
|
||||
cd-gpios = <&gpio4 31 IRQ_TYPE_LEVEL_LOW>; /* gpio127 */
|
||||
cd-gpios = <&gpio4 31 GPIO_ACTIVE_LOW>; /* gpio127 */
|
||||
vmmc-supply = <&vmmc1>;
|
||||
bus-width = <4>;
|
||||
cap-power-off-card;
|
||||
@@ -249,9 +249,9 @@
|
||||
OMAP3_CORE1_IOPAD(0x2110, PIN_INPUT | MUX_MODE0) /* cam_xclka.cam_xclka */
|
||||
OMAP3_CORE1_IOPAD(0x2112, PIN_INPUT | MUX_MODE0) /* cam_pclk.cam_pclk */
|
||||
|
||||
OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE0) /* cam_d0.cam_d0 */
|
||||
OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0) /* cam_d1.cam_d1 */
|
||||
OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0) /* cam_d2.cam_d2 */
|
||||
OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0) /* cam_d0.cam_d0 */
|
||||
OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0) /* cam_d1.cam_d1 */
|
||||
OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT | MUX_MODE0) /* cam_d2.cam_d2 */
|
||||
OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE0) /* cam_d3.cam_d3 */
|
||||
OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE0) /* cam_d4.cam_d4 */
|
||||
OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE0) /* cam_d5.cam_d5 */
|
||||
|
||||
@@ -162,7 +162,7 @@ static struct ti_st_plat_data wilink7_pdata = {
|
||||
.nshutdown_gpio = 162,
|
||||
.dev_name = "/dev/ttyO1",
|
||||
.flow_cntrl = 1,
|
||||
.baud_rate = 300000,
|
||||
.baud_rate = 3000000,
|
||||
};
|
||||
|
||||
static struct platform_device wl128x_device = {
|
||||
|
||||
+2
-2
@@ -126,8 +126,8 @@ static const struct prot_bits section_bits[] = {
|
||||
.val = PMD_SECT_USER,
|
||||
.set = "USR",
|
||||
}, {
|
||||
.mask = L_PMD_SECT_RDONLY,
|
||||
.val = L_PMD_SECT_RDONLY,
|
||||
.mask = L_PMD_SECT_RDONLY | PMD_SECT_AP2,
|
||||
.val = L_PMD_SECT_RDONLY | PMD_SECT_AP2,
|
||||
.set = "ro",
|
||||
.clear = "RW",
|
||||
#elif __LINUX_ARM_ARCH__ >= 6
|
||||
|
||||
+2
-2
@@ -619,8 +619,8 @@ static struct section_perm ro_perms[] = {
|
||||
.start = (unsigned long)_stext,
|
||||
.end = (unsigned long)__init_begin,
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
.mask = ~L_PMD_SECT_RDONLY,
|
||||
.prot = L_PMD_SECT_RDONLY,
|
||||
.mask = ~(L_PMD_SECT_RDONLY | PMD_SECT_AP2),
|
||||
.prot = L_PMD_SECT_RDONLY | PMD_SECT_AP2,
|
||||
#else
|
||||
.mask = ~(PMD_SECT_APX | PMD_SECT_AP_WRITE),
|
||||
.prot = PMD_SECT_APX | PMD_SECT_AP_WRITE,
|
||||
|
||||
@@ -91,6 +91,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
|
||||
((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
|
||||
#define pte_valid_young(pte) \
|
||||
((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF))
|
||||
#define pte_valid_user(pte) \
|
||||
((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
|
||||
|
||||
/*
|
||||
* Could the pte be present in the TLB? We must check mm_tlb_flush_pending
|
||||
@@ -100,6 +102,18 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
|
||||
#define pte_accessible(mm, pte) \
|
||||
(mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid_young(pte))
|
||||
|
||||
/*
|
||||
* p??_access_permitted() is true for valid user mappings (subject to the
|
||||
* write permission check) other than user execute-only which do not have the
|
||||
* PTE_USER bit set. PROT_NONE mappings do not have the PTE_VALID bit set.
|
||||
*/
|
||||
#define pte_access_permitted(pte, write) \
|
||||
(pte_valid_user(pte) && (!(write) || pte_write(pte)))
|
||||
#define pmd_access_permitted(pmd, write) \
|
||||
(pte_access_permitted(pmd_pte(pmd), (write)))
|
||||
#define pud_access_permitted(pud, write) \
|
||||
(pte_access_permitted(pud_pte(pud), (write)))
|
||||
|
||||
static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot)
|
||||
{
|
||||
pte_val(pte) &= ~pgprot_val(prot);
|
||||
|
||||
@@ -220,10 +220,8 @@ void update_vsyscall(struct timekeeper *tk)
|
||||
if (!use_syscall) {
|
||||
/* tkr_mono.cycle_last == tkr_raw.cycle_last */
|
||||
vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
|
||||
vdso_data->raw_time_sec = tk->raw_time.tv_sec;
|
||||
vdso_data->raw_time_nsec = (tk->raw_time.tv_nsec <<
|
||||
tk->tkr_raw.shift) +
|
||||
tk->tkr_raw.xtime_nsec;
|
||||
vdso_data->raw_time_sec = tk->raw_sec;
|
||||
vdso_data->raw_time_nsec = tk->tkr_raw.xtime_nsec;
|
||||
vdso_data->xtime_clock_sec = tk->xtime_sec;
|
||||
vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec;
|
||||
vdso_data->cs_mono_mult = tk->tkr_mono.mult;
|
||||
|
||||
@@ -309,7 +309,7 @@ ENTRY(__kernel_clock_getres)
|
||||
b.ne 4f
|
||||
ldr x2, 6f
|
||||
2:
|
||||
cbz w1, 3f
|
||||
cbz x1, 3f
|
||||
stp xzr, x2, [x1]
|
||||
|
||||
3: /* res == NULL. */
|
||||
|
||||
@@ -330,7 +330,7 @@ bcm47xx_leds_linksys_wrt54g3gv2[] __initconst = {
|
||||
/* Verified on: WRT54GS V1.0 */
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt54g_type_0101[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "green", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(0, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
@@ -22,7 +22,6 @@ dtb-$(CONFIG_DT_NONE) += \
|
||||
bcm63268-comtrend-vr-3032u.dtb \
|
||||
bcm93384wvg.dtb \
|
||||
bcm93384wvg_viper.dtb \
|
||||
bcm96358nb4ser.dtb \
|
||||
bcm96368mvwg.dtb \
|
||||
bcm9ejtagprb.dtb \
|
||||
bcm97125cbmb.dtb \
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <asm/asmmacro-64.h>
|
||||
#endif
|
||||
|
||||
/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
|
||||
#undef fp
|
||||
|
||||
/*
|
||||
* Helper macros for generating raw instruction encodings.
|
||||
*/
|
||||
@@ -105,6 +108,7 @@
|
||||
.macro fpu_save_16odd thread
|
||||
.set push
|
||||
.set mips64r2
|
||||
.set fp=64
|
||||
SET_HARDFLOAT
|
||||
sdc1 $f1, THREAD_FPR1(\thread)
|
||||
sdc1 $f3, THREAD_FPR3(\thread)
|
||||
@@ -163,6 +167,7 @@
|
||||
.macro fpu_restore_16odd thread
|
||||
.set push
|
||||
.set mips64r2
|
||||
.set fp=64
|
||||
SET_HARDFLOAT
|
||||
ldc1 $f1, THREAD_FPR1(\thread)
|
||||
ldc1 $f3, THREAD_FPR3(\thread)
|
||||
@@ -234,9 +239,6 @@
|
||||
.endm
|
||||
|
||||
#ifdef TOOLCHAIN_SUPPORTS_MSA
|
||||
/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
|
||||
#undef fp
|
||||
|
||||
.macro _cfcmsa rd, cs
|
||||
.set push
|
||||
.set mips32r2
|
||||
|
||||
@@ -647,6 +647,19 @@ static const struct user_regset_view user_mips64_view = {
|
||||
.n = ARRAY_SIZE(mips64_regsets),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MIPS32_N32
|
||||
|
||||
static const struct user_regset_view user_mipsn32_view = {
|
||||
.name = "mipsn32",
|
||||
.e_flags = EF_MIPS_ABI2,
|
||||
.e_machine = ELF_ARCH,
|
||||
.ei_osabi = ELF_OSABI,
|
||||
.regsets = mips64_regsets,
|
||||
.n = ARRAY_SIZE(mips64_regsets),
|
||||
};
|
||||
|
||||
#endif /* CONFIG_MIPS32_N32 */
|
||||
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
|
||||
@@ -657,6 +670,10 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
|
||||
#ifdef CONFIG_MIPS32_O32
|
||||
if (test_tsk_thread_flag(task, TIF_32BIT_REGS))
|
||||
return &user_mips_view;
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS32_N32
|
||||
if (test_tsk_thread_flag(task, TIF_32BIT_ADDR))
|
||||
return &user_mipsn32_view;
|
||||
#endif
|
||||
return &user_mips64_view;
|
||||
#endif
|
||||
|
||||
@@ -121,7 +121,7 @@ static int wait_pciephy_busy(void)
|
||||
else
|
||||
break;
|
||||
if (retry++ > WAITRETRY_MAX) {
|
||||
printk(KERN_WARN "PCIE-PHY retry failed.\n");
|
||||
pr_warn("PCIE-PHY retry failed.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,8 @@ static struct rt2880_pmx_func i2c_grp_mt7628[] = {
|
||||
FUNC("i2c", 0, 4, 2),
|
||||
};
|
||||
|
||||
static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) };
|
||||
static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) };
|
||||
static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("refclk", 0, 37, 1) };
|
||||
static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) };
|
||||
static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) };
|
||||
static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
|
||||
|
||||
|
||||
@@ -690,15 +690,15 @@ cas_action:
|
||||
/* ELF32 Process entry path */
|
||||
lws_compare_and_swap_2:
|
||||
#ifdef CONFIG_64BIT
|
||||
/* Clip the input registers */
|
||||
/* Clip the input registers. We don't need to clip %r23 as we
|
||||
only use it for word operations */
|
||||
depdi 0, 31, 32, %r26
|
||||
depdi 0, 31, 32, %r25
|
||||
depdi 0, 31, 32, %r24
|
||||
depdi 0, 31, 32, %r23
|
||||
#endif
|
||||
|
||||
/* Check the validity of the size pointer */
|
||||
subi,>>= 4, %r23, %r0
|
||||
subi,>>= 3, %r23, %r0
|
||||
b,n lws_exit_nosys
|
||||
|
||||
/* Jump to the functions which will load the old and new values into
|
||||
|
||||
@@ -102,7 +102,7 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
|
||||
static void do_signal(struct task_struct *tsk)
|
||||
{
|
||||
sigset_t *oldset = sigmask_to_save();
|
||||
struct ksignal ksig;
|
||||
struct ksignal ksig = { .sig = 0 };
|
||||
int ret;
|
||||
int is32 = is_32bit_task();
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _ASM_S390_PROTOTYPES_H
|
||||
|
||||
#include <linux/kvm_host.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <asm/fpu/api.h>
|
||||
#include <asm-generic/asm-prototypes.h>
|
||||
|
||||
#endif /* _ASM_S390_PROTOTYPES_H */
|
||||
@@ -34,8 +34,8 @@ static inline void restore_access_regs(unsigned int *acrs)
|
||||
save_access_regs(&prev->thread.acrs[0]); \
|
||||
save_ri_cb(prev->thread.ri_cb); \
|
||||
} \
|
||||
if (next->mm) { \
|
||||
update_cr_regs(next); \
|
||||
if (next->mm) { \
|
||||
set_cpu_flag(CIF_FPU); \
|
||||
restore_access_regs(&next->thread.acrs[0]); \
|
||||
restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \
|
||||
|
||||
@@ -1548,6 +1548,7 @@ static struct s390_insn opcode_e7[] = {
|
||||
{ "vfsq", 0xce, INSTR_VRR_VV000MM },
|
||||
{ "vfs", 0xe2, INSTR_VRR_VVV00MM },
|
||||
{ "vftci", 0x4a, INSTR_VRI_VVIMM },
|
||||
{ "", 0, INSTR_INVALID }
|
||||
};
|
||||
|
||||
static struct s390_insn opcode_eb[] = {
|
||||
@@ -1953,7 +1954,7 @@ void show_code(struct pt_regs *regs)
|
||||
{
|
||||
char *mode = user_mode(regs) ? "User" : "Krnl";
|
||||
unsigned char code[64];
|
||||
char buffer[64], *ptr;
|
||||
char buffer[128], *ptr;
|
||||
mm_segment_t old_fs;
|
||||
unsigned long addr;
|
||||
int start, end, opsize, hops, i;
|
||||
@@ -2016,7 +2017,7 @@ void show_code(struct pt_regs *regs)
|
||||
start += opsize;
|
||||
pr_cont("%s", buffer);
|
||||
ptr = buffer;
|
||||
ptr += sprintf(ptr, "\n ");
|
||||
ptr += sprintf(ptr, "\n\t ");
|
||||
hops++;
|
||||
}
|
||||
pr_cont("\n");
|
||||
|
||||
@@ -345,8 +345,10 @@ static __init void detect_machine_facilities(void)
|
||||
S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
|
||||
if (test_facility(40))
|
||||
S390_lowcore.machine_flags |= MACHINE_FLAG_LPP;
|
||||
if (test_facility(50) && test_facility(73))
|
||||
if (test_facility(50) && test_facility(73)) {
|
||||
S390_lowcore.machine_flags |= MACHINE_FLAG_TE;
|
||||
__ctl_set_bit(0, 55);
|
||||
}
|
||||
if (test_facility(51))
|
||||
S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC;
|
||||
if (test_facility(129)) {
|
||||
|
||||
@@ -120,6 +120,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
|
||||
memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
|
||||
memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
|
||||
clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
|
||||
p->thread.per_flags = 0;
|
||||
/* Initialize per thread user and system timer values */
|
||||
ti = task_thread_info(p);
|
||||
ti->user_timer = 0;
|
||||
|
||||
@@ -47,11 +47,13 @@ void exit_thread_runtime_instr(void)
|
||||
{
|
||||
struct task_struct *task = current;
|
||||
|
||||
preempt_disable();
|
||||
if (!task->thread.ri_cb)
|
||||
return;
|
||||
disable_runtime_instr();
|
||||
kfree(task->thread.ri_cb);
|
||||
task->thread.ri_cb = NULL;
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE1(s390_runtime_instr, int, command)
|
||||
@@ -62,9 +64,7 @@ SYSCALL_DEFINE1(s390_runtime_instr, int, command)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (command == S390_RUNTIME_INSTR_STOP) {
|
||||
preempt_disable();
|
||||
exit_thread_runtime_instr();
|
||||
preempt_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+11
-1
@@ -246,9 +246,14 @@ static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id)
|
||||
recalculate_apic_map(apic->vcpu->kvm);
|
||||
}
|
||||
|
||||
static inline u32 kvm_apic_calc_x2apic_ldr(u32 id)
|
||||
{
|
||||
return ((id >> 4) << 16) | (1 << (id & 0xf));
|
||||
}
|
||||
|
||||
static inline void kvm_apic_set_x2apic_id(struct kvm_lapic *apic, u32 id)
|
||||
{
|
||||
u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
|
||||
u32 ldr = kvm_apic_calc_x2apic_ldr(id);
|
||||
|
||||
kvm_lapic_set_reg(apic, APIC_ID, id);
|
||||
kvm_lapic_set_reg(apic, APIC_LDR, ldr);
|
||||
@@ -2029,6 +2034,7 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
if (apic_x2apic_mode(vcpu->arch.apic)) {
|
||||
u32 *id = (u32 *)(s->regs + APIC_ID);
|
||||
u32 *ldr = (u32 *)(s->regs + APIC_LDR);
|
||||
|
||||
if (vcpu->kvm->arch.x2apic_format) {
|
||||
if (*id != vcpu->vcpu_id)
|
||||
@@ -2039,6 +2045,10 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
|
||||
else
|
||||
*id <<= 24;
|
||||
}
|
||||
|
||||
/* In x2APIC mode, the LDR is fixed and based on the id */
|
||||
if (set)
|
||||
*ldr = kvm_apic_calc_x2apic_ldr(*id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -2149,6 +2149,8 @@ static int ud_interception(struct vcpu_svm *svm)
|
||||
int er;
|
||||
|
||||
er = emulate_instruction(&svm->vcpu, EMULTYPE_TRAP_UD);
|
||||
if (er == EMULATE_USER_EXIT)
|
||||
return 0;
|
||||
if (er != EMULATE_DONE)
|
||||
kvm_queue_exception(&svm->vcpu, UD_VECTOR);
|
||||
return 1;
|
||||
@@ -3583,6 +3585,13 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
|
||||
u32 ecx = msr->index;
|
||||
u64 data = msr->data;
|
||||
switch (ecx) {
|
||||
case MSR_IA32_CR_PAT:
|
||||
if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
|
||||
return 1;
|
||||
vcpu->arch.pat = data;
|
||||
svm->vmcb->save.g_pat = data;
|
||||
mark_dirty(svm->vmcb, VMCB_NPT);
|
||||
break;
|
||||
case MSR_IA32_TSC:
|
||||
kvm_write_tsc(vcpu, msr);
|
||||
break;
|
||||
|
||||
@@ -5502,6 +5502,8 @@ static int handle_exception(struct kvm_vcpu *vcpu)
|
||||
return 1;
|
||||
}
|
||||
er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD);
|
||||
if (er == EMULATE_USER_EXIT)
|
||||
return 0;
|
||||
if (er != EMULATE_DONE)
|
||||
kvm_queue_exception(vcpu, UD_VECTOR);
|
||||
return 1;
|
||||
@@ -10714,6 +10716,8 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
|
||||
vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->host_ia32_sysenter_eip);
|
||||
vmcs_writel(GUEST_IDTR_BASE, vmcs12->host_idtr_base);
|
||||
vmcs_writel(GUEST_GDTR_BASE, vmcs12->host_gdtr_base);
|
||||
vmcs_write32(GUEST_IDTR_LIMIT, 0xFFFF);
|
||||
vmcs_write32(GUEST_GDTR_LIMIT, 0xFFFF);
|
||||
|
||||
/* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */
|
||||
if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS)
|
||||
|
||||
@@ -1797,6 +1797,9 @@ static void kvm_setup_pvclock_page(struct kvm_vcpu *v)
|
||||
*/
|
||||
BUILD_BUG_ON(offsetof(struct pvclock_vcpu_time_info, version) != 0);
|
||||
|
||||
if (guest_hv_clock.version & 1)
|
||||
++guest_hv_clock.version; /* first time write, random junk */
|
||||
|
||||
vcpu->hv_clock.version = guest_hv_clock.version + 1;
|
||||
kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
|
||||
&vcpu->hv_clock,
|
||||
@@ -5576,6 +5579,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
|
||||
if (reexecute_instruction(vcpu, cr2, write_fault_to_spt,
|
||||
emulation_type))
|
||||
return EMULATE_DONE;
|
||||
if (ctxt->have_exception && inject_emulated_exception(vcpu))
|
||||
return EMULATE_DONE;
|
||||
if (emulation_type & EMULTYPE_SKIP)
|
||||
return EMULATE_FAIL;
|
||||
return handle_emulation_failure(vcpu);
|
||||
|
||||
@@ -896,7 +896,7 @@ EndTable
|
||||
|
||||
GrpTable: Grp3_1
|
||||
0: TEST Eb,Ib
|
||||
1:
|
||||
1: TEST Eb,Ib
|
||||
2: NOT Eb
|
||||
3: NEG Eb
|
||||
4: MUL AL,Eb
|
||||
|
||||
+10
-1
@@ -1392,7 +1392,17 @@ good_area:
|
||||
* make sure we exit gracefully rather than endlessly redo
|
||||
* the fault. Since we never set FAULT_FLAG_RETRY_NOWAIT, if
|
||||
* we get VM_FAULT_RETRY back, the mmap_sem has been unlocked.
|
||||
*
|
||||
* Note that handle_userfault() may also release and reacquire mmap_sem
|
||||
* (and not return with VM_FAULT_RETRY), when returning to userland to
|
||||
* repeat the page fault later with a VM_FAULT_NOPAGE retval
|
||||
* (potentially after handling any pending signal during the return to
|
||||
* userland). The return to userland is identified whenever
|
||||
* FAULT_FLAG_USER|FAULT_FLAG_KILLABLE are both set in flags.
|
||||
* Thus we have to be careful about not touching vma after handling the
|
||||
* fault, so we read the pkey beforehand.
|
||||
*/
|
||||
pkey = vma_pkey(vma);
|
||||
fault = handle_mm_fault(vma, address, flags);
|
||||
major |= fault & VM_FAULT_MAJOR;
|
||||
|
||||
@@ -1419,7 +1429,6 @@ good_area:
|
||||
return;
|
||||
}
|
||||
|
||||
pkey = vma_pkey(vma);
|
||||
up_read(&mm->mmap_sem);
|
||||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
mm_fault_error(regs, error_code, address, &pkey, fault);
|
||||
|
||||
@@ -284,6 +284,7 @@ EXPORT_SYMBOL(blk_stop_queue);
|
||||
void blk_sync_queue(struct request_queue *q)
|
||||
{
|
||||
del_timer_sync(&q->timeout);
|
||||
cancel_work_sync(&q->timeout_work);
|
||||
|
||||
if (q->mq_ops) {
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
@@ -722,6 +723,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
|
||||
setup_timer(&q->backing_dev_info.laptop_mode_wb_timer,
|
||||
laptop_mode_timer_fn, (unsigned long) q);
|
||||
setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
|
||||
INIT_WORK(&q->timeout_work, NULL);
|
||||
INIT_LIST_HEAD(&q->queue_head);
|
||||
INIT_LIST_HEAD(&q->timeout_list);
|
||||
INIT_LIST_HEAD(&q->icq_list);
|
||||
|
||||
@@ -135,8 +135,6 @@ void blk_timeout_work(struct work_struct *work)
|
||||
struct request *rq, *tmp;
|
||||
int next_set = 0;
|
||||
|
||||
if (blk_queue_enter(q, true))
|
||||
return;
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
|
||||
list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list)
|
||||
@@ -146,7 +144,6 @@ void blk_timeout_work(struct work_struct *work)
|
||||
mod_timer(&q->timeout, round_jiffies_up(next));
|
||||
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
blk_queue_exit(q);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -208,4 +208,6 @@ source "drivers/hisi/Kconfig"
|
||||
|
||||
source "drivers/fpga/Kconfig"
|
||||
|
||||
source "drivers/tee/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -175,4 +175,5 @@ obj-$(CONFIG_STM) += hwtracing/stm/
|
||||
obj-$(CONFIG_ANDROID) += android/
|
||||
obj-$(CONFIG_NVMEM) += nvmem/
|
||||
obj-$(CONFIG_FPGA) += fpga/
|
||||
obj-$(CONFIG_TEE) += tee/
|
||||
obj-$(CONFIG_HISILICON_PLATFORM)+= hisi/
|
||||
|
||||
+6
-4
@@ -482,7 +482,10 @@ static inline void __acpi_ec_enable_event(struct acpi_ec *ec)
|
||||
{
|
||||
if (!test_and_set_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags))
|
||||
ec_log_drv("event unblocked");
|
||||
if (!test_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
|
||||
/*
|
||||
* Unconditionally invoke this once after enabling the event
|
||||
* handling mechanism to detect the pending events.
|
||||
*/
|
||||
advance_transaction(ec);
|
||||
}
|
||||
|
||||
@@ -1458,11 +1461,10 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events)
|
||||
if (test_bit(EC_FLAGS_STARTED, &ec->flags) &&
|
||||
ec->reference_count >= 1)
|
||||
acpi_ec_enable_gpe(ec, true);
|
||||
|
||||
}
|
||||
}
|
||||
/* EC is fully operational, allow queries */
|
||||
acpi_ec_enable_event(ec);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2329,8 +2329,8 @@ static void ata_eh_link_autopsy(struct ata_link *link)
|
||||
if (dev->flags & ATA_DFLAG_DUBIOUS_XFER)
|
||||
eflags |= ATA_EFLAG_DUBIOUS_XFER;
|
||||
ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask);
|
||||
}
|
||||
trace_ata_eh_link_autopsy(dev, ehc->i.action, all_err_mask);
|
||||
}
|
||||
DPRINTK("EXIT\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -348,6 +348,7 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: Failed to add OPP, %d\n", __func__,
|
||||
ret);
|
||||
of_node_put(np);
|
||||
goto free_table;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,8 +527,18 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
|
||||
static const struct freq_tbl ftbl_gcc_apps_clk[] = {
|
||||
F(48000000, P_XO, 1, 0, 0),
|
||||
F(200000000, P_FEPLL200, 1, 0, 0),
|
||||
F(384000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(413000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(448000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(488000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(500000000, P_FEPLL500, 1, 0, 0),
|
||||
F(626000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(512000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(537000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(565000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(597000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(632000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(672000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
F(716000000, P_DDRPLLAPSS, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -468,8 +468,8 @@ static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents,
|
||||
static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents,
|
||||
0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
|
||||
0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
|
||||
static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", daudio_parents,
|
||||
0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
|
||||
0x0cc, BIT(8), 0);
|
||||
|
||||
@@ -752,6 +752,13 @@ static const struct sunxi_ccu_desc sun8i_a33_ccu_desc = {
|
||||
.num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets),
|
||||
};
|
||||
|
||||
static struct ccu_mux_nb sun8i_a33_cpu_nb = {
|
||||
.common = &cpux_clk.common,
|
||||
.cm = &cpux_clk.mux,
|
||||
.delay_us = 1, /* > 8 clock cycles at 24 MHz */
|
||||
.bypass_index = 1, /* index of 24 MHz oscillator */
|
||||
};
|
||||
|
||||
static void __init sun8i_a33_ccu_setup(struct device_node *node)
|
||||
{
|
||||
void __iomem *reg;
|
||||
@@ -775,6 +782,9 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
|
||||
writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
|
||||
|
||||
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
|
||||
&sun8i_a33_cpu_nb);
|
||||
}
|
||||
CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
|
||||
sun8i_a33_ccu_setup);
|
||||
|
||||
@@ -265,8 +265,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
|
||||
|
||||
/* Get configuration for the ATL instances */
|
||||
snprintf(prop, sizeof(prop), "atl%u", i);
|
||||
of_node_get(node);
|
||||
cfg_node = of_find_node_by_name(node, prop);
|
||||
cfg_node = of_get_child_by_name(node, prop);
|
||||
if (cfg_node) {
|
||||
ret = of_property_read_u32(cfg_node, "bws",
|
||||
&cdesc->bws);
|
||||
|
||||
@@ -273,7 +273,8 @@ struct mv_cesa_op_ctx {
|
||||
#define CESA_TDMA_SRC_IN_SRAM BIT(30)
|
||||
#define CESA_TDMA_END_OF_REQ BIT(29)
|
||||
#define CESA_TDMA_BREAK_CHAIN BIT(28)
|
||||
#define CESA_TDMA_TYPE_MSK GENMASK(27, 0)
|
||||
#define CESA_TDMA_SET_STATE BIT(27)
|
||||
#define CESA_TDMA_TYPE_MSK GENMASK(26, 0)
|
||||
#define CESA_TDMA_DUMMY 0
|
||||
#define CESA_TDMA_DATA 1
|
||||
#define CESA_TDMA_OP 2
|
||||
|
||||
@@ -280,13 +280,32 @@ static void mv_cesa_ahash_std_prepare(struct ahash_request *req)
|
||||
sreq->offset = 0;
|
||||
}
|
||||
|
||||
static void mv_cesa_ahash_dma_step(struct ahash_request *req)
|
||||
{
|
||||
struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
|
||||
struct mv_cesa_req *base = &creq->base;
|
||||
|
||||
/* We must explicitly set the digest state. */
|
||||
if (base->chain.first->flags & CESA_TDMA_SET_STATE) {
|
||||
struct mv_cesa_engine *engine = base->engine;
|
||||
int i;
|
||||
|
||||
/* Set the hash state in the IVDIG regs. */
|
||||
for (i = 0; i < ARRAY_SIZE(creq->state); i++)
|
||||
writel_relaxed(creq->state[i], engine->regs +
|
||||
CESA_IVDIG(i));
|
||||
}
|
||||
|
||||
mv_cesa_dma_step(base);
|
||||
}
|
||||
|
||||
static void mv_cesa_ahash_step(struct crypto_async_request *req)
|
||||
{
|
||||
struct ahash_request *ahashreq = ahash_request_cast(req);
|
||||
struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
|
||||
|
||||
if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
|
||||
mv_cesa_dma_step(&creq->base);
|
||||
mv_cesa_ahash_dma_step(ahashreq);
|
||||
else
|
||||
mv_cesa_ahash_std_step(ahashreq);
|
||||
}
|
||||
@@ -562,11 +581,15 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
|
||||
struct mv_cesa_ahash_dma_iter iter;
|
||||
struct mv_cesa_op_ctx *op = NULL;
|
||||
unsigned int frag_len;
|
||||
bool set_state = false;
|
||||
int ret;
|
||||
|
||||
basereq->chain.first = NULL;
|
||||
basereq->chain.last = NULL;
|
||||
|
||||
if (!mv_cesa_mac_op_is_first_frag(&creq->op_tmpl))
|
||||
set_state = true;
|
||||
|
||||
if (creq->src_nents) {
|
||||
ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
|
||||
DMA_TO_DEVICE);
|
||||
@@ -650,6 +673,15 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
|
||||
basereq->chain.last->flags |= (CESA_TDMA_END_OF_REQ |
|
||||
CESA_TDMA_BREAK_CHAIN);
|
||||
|
||||
if (set_state) {
|
||||
/*
|
||||
* Put the CESA_TDMA_SET_STATE flag on the first tdma desc to
|
||||
* let the step logic know that the IVDIG registers should be
|
||||
* explicitly set before launching a TDMA chain.
|
||||
*/
|
||||
basereq->chain.first->flags |= CESA_TDMA_SET_STATE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_tdma:
|
||||
|
||||
@@ -112,7 +112,14 @@ void mv_cesa_tdma_chain(struct mv_cesa_engine *engine,
|
||||
last->next = dreq->chain.first;
|
||||
engine->chain.last = dreq->chain.last;
|
||||
|
||||
if (!(last->flags & CESA_TDMA_BREAK_CHAIN))
|
||||
/*
|
||||
* Break the DMA chain if the CESA_TDMA_BREAK_CHAIN is set on
|
||||
* the last element of the current chain, or if the request
|
||||
* being queued needs the IV regs to be set before lauching
|
||||
* the request.
|
||||
*/
|
||||
if (!(last->flags & CESA_TDMA_BREAK_CHAIN) &&
|
||||
!(dreq->chain.first->flags & CESA_TDMA_SET_STATE))
|
||||
last->next_dma = dreq->chain.first->cur_dma;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,6 +813,7 @@ static int zx_dma_probe(struct platform_device *op)
|
||||
INIT_LIST_HEAD(&d->slave.channels);
|
||||
dma_cap_set(DMA_SLAVE, d->slave.cap_mask);
|
||||
dma_cap_set(DMA_MEMCPY, d->slave.cap_mask);
|
||||
dma_cap_set(DMA_CYCLIC, d->slave.cap_mask);
|
||||
dma_cap_set(DMA_PRIVATE, d->slave.cap_mask);
|
||||
d->slave.dev = &op->dev;
|
||||
d->slave.device_free_chan_resources = zx_dma_free_chan_resources;
|
||||
|
||||
@@ -126,7 +126,7 @@ static int mockup_gpio_probe(struct platform_device *pdev)
|
||||
int i;
|
||||
int base;
|
||||
int ngpio;
|
||||
char chip_name[sizeof(GPIO_NAME) + 3];
|
||||
char *chip_name;
|
||||
|
||||
if (gpio_mockup_params_nr < 2)
|
||||
return -EINVAL;
|
||||
@@ -146,8 +146,12 @@ static int mockup_gpio_probe(struct platform_device *pdev)
|
||||
ngpio = gpio_mockup_ranges[i * 2 + 1] - base;
|
||||
|
||||
if (ngpio >= 0) {
|
||||
sprintf(chip_name, "%s-%c", GPIO_NAME,
|
||||
chip_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s-%c", GPIO_NAME,
|
||||
pins_name_start + i);
|
||||
if (!chip_name)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mockup_gpio_add(dev, &cntr[i],
|
||||
chip_name, base, ngpio);
|
||||
} else {
|
||||
|
||||
@@ -1788,34 +1788,32 @@ void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev)
|
||||
WREG32(mmBIOS_SCRATCH_0 + i, adev->bios_scratch[i]);
|
||||
}
|
||||
|
||||
/* Atom needs data in little endian format
|
||||
* so swap as appropriate when copying data to
|
||||
* or from atom. Note that atom operates on
|
||||
* dw units.
|
||||
/* Atom needs data in little endian format so swap as appropriate when copying
|
||||
* data to or from atom. Note that atom operates on dw units.
|
||||
*
|
||||
* Use to_le=true when sending data to atom and provide at least
|
||||
* ALIGN(num_bytes,4) bytes in the dst buffer.
|
||||
*
|
||||
* Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
|
||||
* byes in the src buffer.
|
||||
*/
|
||||
void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */
|
||||
u32 *dst32, *src32;
|
||||
u32 src_tmp[5], dst_tmp[5];
|
||||
int i;
|
||||
u8 align_num_bytes = ALIGN(num_bytes, 4);
|
||||
|
||||
memcpy(src_tmp, src, num_bytes);
|
||||
src32 = (u32 *)src_tmp;
|
||||
dst32 = (u32 *)dst_tmp;
|
||||
if (to_le) {
|
||||
for (i = 0; i < ((num_bytes + 3) / 4); i++)
|
||||
dst32[i] = cpu_to_le32(src32[i]);
|
||||
memcpy(dst, dst_tmp, num_bytes);
|
||||
memcpy(src_tmp, src, num_bytes);
|
||||
for (i = 0; i < align_num_bytes / 4; i++)
|
||||
dst_tmp[i] = cpu_to_le32(src_tmp[i]);
|
||||
memcpy(dst, dst_tmp, align_num_bytes);
|
||||
} else {
|
||||
u8 dws = num_bytes & ~3;
|
||||
for (i = 0; i < ((num_bytes + 3) / 4); i++)
|
||||
dst32[i] = le32_to_cpu(src32[i]);
|
||||
memcpy(dst, dst_tmp, dws);
|
||||
if (num_bytes % 4) {
|
||||
for (i = 0; i < (num_bytes % 4); i++)
|
||||
dst[dws+i] = dst_tmp[dws+i];
|
||||
}
|
||||
memcpy(src_tmp, src, align_num_bytes);
|
||||
for (i = 0; i < align_num_bytes / 4; i++)
|
||||
dst_tmp[i] = le32_to_cpu(src_tmp[i]);
|
||||
memcpy(dst, dst_tmp, num_bytes);
|
||||
}
|
||||
#else
|
||||
memcpy(dst, src, num_bytes);
|
||||
|
||||
@@ -648,7 +648,7 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
|
||||
uint32_t allocated = 0;
|
||||
uint32_t tmp, handle = 0;
|
||||
uint32_t *size = &tmp;
|
||||
int i, r, idx = 0;
|
||||
int i, r = 0, idx = 0;
|
||||
|
||||
r = amdgpu_cs_sysvm_access_required(p);
|
||||
if (r)
|
||||
|
||||
@@ -744,7 +744,7 @@ error_free:
|
||||
int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm)
|
||||
{
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
r = amdgpu_vm_update_pd_or_shadow(adev, vm, true);
|
||||
if (r)
|
||||
|
||||
@@ -850,9 +850,9 @@ static int init_over_drive_limits(
|
||||
const ATOM_Tonga_POWERPLAYTABLE *powerplay_table)
|
||||
{
|
||||
hwmgr->platform_descriptor.overdriveLimit.engineClock =
|
||||
le16_to_cpu(powerplay_table->ulMaxODEngineClock);
|
||||
le32_to_cpu(powerplay_table->ulMaxODEngineClock);
|
||||
hwmgr->platform_descriptor.overdriveLimit.memoryClock =
|
||||
le16_to_cpu(powerplay_table->ulMaxODMemoryClock);
|
||||
le32_to_cpu(powerplay_table->ulMaxODMemoryClock);
|
||||
|
||||
hwmgr->platform_descriptor.minOverdriveVDDC = 0;
|
||||
hwmgr->platform_descriptor.maxOverdriveVDDC = 0;
|
||||
|
||||
@@ -4,3 +4,5 @@ armada-y += armada_510.o
|
||||
armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
|
||||
|
||||
obj-$(CONFIG_DRM_ARMADA) := armada.o
|
||||
|
||||
CFLAGS_armada_trace.o := -I$(src)
|
||||
|
||||
@@ -348,14 +348,12 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
|
||||
|
||||
BUG_ON(!hole_node->hole_follows || node->allocated);
|
||||
|
||||
if (adj_start < start)
|
||||
adj_start = start;
|
||||
if (adj_end > end)
|
||||
adj_end = end;
|
||||
|
||||
if (mm->color_adjust)
|
||||
mm->color_adjust(hole_node, color, &adj_start, &adj_end);
|
||||
|
||||
adj_start = max(adj_start, start);
|
||||
adj_end = min(adj_end, end);
|
||||
|
||||
if (flags & DRM_MM_CREATE_TOP)
|
||||
adj_start = adj_end - size;
|
||||
|
||||
@@ -566,17 +564,15 @@ static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_
|
||||
flags & DRM_MM_SEARCH_BELOW) {
|
||||
u64 hole_size = adj_end - adj_start;
|
||||
|
||||
if (adj_start < start)
|
||||
adj_start = start;
|
||||
if (adj_end > end)
|
||||
adj_end = end;
|
||||
|
||||
if (mm->color_adjust) {
|
||||
mm->color_adjust(entry, color, &adj_start, &adj_end);
|
||||
if (adj_end <= adj_start)
|
||||
continue;
|
||||
}
|
||||
|
||||
adj_start = max(adj_start, start);
|
||||
adj_end = min(adj_end, end);
|
||||
|
||||
if (!check_free_hole(adj_start, adj_end, size, alignment))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -521,9 +521,12 @@ static void ade_crtc_atomic_begin(struct drm_crtc *crtc,
|
||||
{
|
||||
struct ade_crtc *acrtc = to_ade_crtc(crtc);
|
||||
struct ade_hw_ctx *ctx = acrtc->ctx;
|
||||
struct drm_display_mode *mode = &crtc->state->mode;
|
||||
struct drm_display_mode *adj_mode = &crtc->state->adjusted_mode;
|
||||
|
||||
if (!ctx->power_on)
|
||||
(void)ade_power_up(ctx);
|
||||
ade_ldi_set_mode(acrtc, mode, adj_mode);
|
||||
}
|
||||
|
||||
static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
|
||||
@@ -457,6 +457,7 @@ struct intel_crtc_scaler_state {
|
||||
|
||||
struct intel_pipe_wm {
|
||||
struct intel_wm_level wm[5];
|
||||
struct intel_wm_level raw_wm[5];
|
||||
uint32_t linetime;
|
||||
bool fbc_wm_enabled;
|
||||
bool pipe_enabled;
|
||||
|
||||
@@ -430,7 +430,9 @@ static bool
|
||||
gmbus_is_index_read(struct i2c_msg *msgs, int i, int num)
|
||||
{
|
||||
return (i + 1 < num &&
|
||||
!(msgs[i].flags & I2C_M_RD) && msgs[i].len <= 2 &&
|
||||
msgs[i].addr == msgs[i + 1].addr &&
|
||||
!(msgs[i].flags & I2C_M_RD) &&
|
||||
(msgs[i].len == 1 || msgs[i].len == 2) &&
|
||||
(msgs[i + 1].flags & I2C_M_RD));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
#include <linux/cpufreq.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include "i915_drv.h"
|
||||
#include "intel_drv.h"
|
||||
#include "../../../platform/x86/intel_ips.h"
|
||||
@@ -2018,9 +2017,9 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
|
||||
const struct intel_crtc *intel_crtc,
|
||||
int level,
|
||||
struct intel_crtc_state *cstate,
|
||||
const struct intel_plane_state *pristate,
|
||||
const struct intel_plane_state *sprstate,
|
||||
const struct intel_plane_state *curstate,
|
||||
struct intel_plane_state *pristate,
|
||||
struct intel_plane_state *sprstate,
|
||||
struct intel_plane_state *curstate,
|
||||
struct intel_wm_level *result)
|
||||
{
|
||||
uint16_t pri_latency = dev_priv->wm.pri_latency[level];
|
||||
@@ -2342,24 +2341,28 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate)
|
||||
struct intel_pipe_wm *pipe_wm;
|
||||
struct drm_device *dev = state->dev;
|
||||
const struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_plane *plane;
|
||||
const struct drm_plane_state *plane_state;
|
||||
const struct intel_plane_state *pristate = NULL;
|
||||
const struct intel_plane_state *sprstate = NULL;
|
||||
const struct intel_plane_state *curstate = NULL;
|
||||
struct intel_plane *intel_plane;
|
||||
struct intel_plane_state *pristate = NULL;
|
||||
struct intel_plane_state *sprstate = NULL;
|
||||
struct intel_plane_state *curstate = NULL;
|
||||
int level, max_level = ilk_wm_max_level(dev), usable_level;
|
||||
struct ilk_wm_maximums max;
|
||||
|
||||
pipe_wm = &cstate->wm.ilk.optimal;
|
||||
|
||||
drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &cstate->base) {
|
||||
const struct intel_plane_state *ps = to_intel_plane_state(plane_state);
|
||||
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
||||
struct intel_plane_state *ps;
|
||||
|
||||
if (plane->type == DRM_PLANE_TYPE_PRIMARY)
|
||||
ps = intel_atomic_get_existing_plane_state(state,
|
||||
intel_plane);
|
||||
if (!ps)
|
||||
continue;
|
||||
|
||||
if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY)
|
||||
pristate = ps;
|
||||
else if (plane->type == DRM_PLANE_TYPE_OVERLAY)
|
||||
else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY)
|
||||
sprstate = ps;
|
||||
else if (plane->type == DRM_PLANE_TYPE_CURSOR)
|
||||
else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
|
||||
curstate = ps;
|
||||
}
|
||||
|
||||
@@ -2381,9 +2384,11 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate)
|
||||
if (pipe_wm->sprites_scaled)
|
||||
usable_level = 0;
|
||||
|
||||
memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm));
|
||||
ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate,
|
||||
pristate, sprstate, curstate, &pipe_wm->wm[0]);
|
||||
pristate, sprstate, curstate, &pipe_wm->raw_wm[0]);
|
||||
|
||||
memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm));
|
||||
pipe_wm->wm[0] = pipe_wm->raw_wm[0];
|
||||
|
||||
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
|
||||
pipe_wm->linetime = hsw_compute_linetime_wm(cstate);
|
||||
@@ -2393,8 +2398,8 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate)
|
||||
|
||||
ilk_compute_wm_reg_maximums(dev, 1, &max);
|
||||
|
||||
for (level = 1; level <= usable_level; level++) {
|
||||
struct intel_wm_level *wm = &pipe_wm->wm[level];
|
||||
for (level = 1; level <= max_level; level++) {
|
||||
struct intel_wm_level *wm = &pipe_wm->raw_wm[level];
|
||||
|
||||
ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate,
|
||||
pristate, sprstate, curstate, wm);
|
||||
@@ -2404,10 +2409,13 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate)
|
||||
* register maximums since such watermarks are
|
||||
* always invalid.
|
||||
*/
|
||||
if (!ilk_validate_wm_level(level, &max, wm)) {
|
||||
memset(wm, 0, sizeof(*wm));
|
||||
break;
|
||||
}
|
||||
if (level > usable_level)
|
||||
continue;
|
||||
|
||||
if (ilk_validate_wm_level(level, &max, wm))
|
||||
pipe_wm->wm[level] = *wm;
|
||||
else
|
||||
usable_level = level;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -321,7 +321,8 @@ static void mtk_drm_unbind(struct device *dev)
|
||||
{
|
||||
struct mtk_drm_private *private = dev_get_drvdata(dev);
|
||||
|
||||
drm_put_dev(private->drm);
|
||||
drm_dev_unregister(private->drm);
|
||||
drm_dev_unref(private->drm);
|
||||
private->drm = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -369,6 +369,7 @@ static int panel_simple_remove(struct device *dev)
|
||||
drm_panel_remove(&panel->base);
|
||||
|
||||
panel_simple_disable(&panel->base);
|
||||
panel_simple_unprepare(&panel->base);
|
||||
|
||||
if (panel->ddc)
|
||||
put_device(&panel->ddc->dev);
|
||||
@@ -384,6 +385,7 @@ static void panel_simple_shutdown(struct device *dev)
|
||||
struct panel_simple *panel = dev_get_drvdata(dev);
|
||||
|
||||
panel_simple_disable(&panel->base);
|
||||
panel_simple_unprepare(&panel->base);
|
||||
}
|
||||
|
||||
static const struct drm_display_mode ampire_am800480r3tmqwa1h_mode = {
|
||||
|
||||
@@ -45,34 +45,32 @@ static char *pre_emph_names[] = {
|
||||
|
||||
/***** radeon AUX functions *****/
|
||||
|
||||
/* Atom needs data in little endian format
|
||||
* so swap as appropriate when copying data to
|
||||
* or from atom. Note that atom operates on
|
||||
* dw units.
|
||||
/* Atom needs data in little endian format so swap as appropriate when copying
|
||||
* data to or from atom. Note that atom operates on dw units.
|
||||
*
|
||||
* Use to_le=true when sending data to atom and provide at least
|
||||
* ALIGN(num_bytes,4) bytes in the dst buffer.
|
||||
*
|
||||
* Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
|
||||
* byes in the src buffer.
|
||||
*/
|
||||
void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */
|
||||
u32 *dst32, *src32;
|
||||
u32 src_tmp[5], dst_tmp[5];
|
||||
int i;
|
||||
u8 align_num_bytes = ALIGN(num_bytes, 4);
|
||||
|
||||
memcpy(src_tmp, src, num_bytes);
|
||||
src32 = (u32 *)src_tmp;
|
||||
dst32 = (u32 *)dst_tmp;
|
||||
if (to_le) {
|
||||
for (i = 0; i < ((num_bytes + 3) / 4); i++)
|
||||
dst32[i] = cpu_to_le32(src32[i]);
|
||||
memcpy(dst, dst_tmp, num_bytes);
|
||||
memcpy(src_tmp, src, num_bytes);
|
||||
for (i = 0; i < align_num_bytes / 4; i++)
|
||||
dst_tmp[i] = cpu_to_le32(src_tmp[i]);
|
||||
memcpy(dst, dst_tmp, align_num_bytes);
|
||||
} else {
|
||||
u8 dws = num_bytes & ~3;
|
||||
for (i = 0; i < ((num_bytes + 3) / 4); i++)
|
||||
dst32[i] = le32_to_cpu(src32[i]);
|
||||
memcpy(dst, dst_tmp, dws);
|
||||
if (num_bytes % 4) {
|
||||
for (i = 0; i < (num_bytes % 4); i++)
|
||||
dst[dws+i] = dst_tmp[dws+i];
|
||||
}
|
||||
memcpy(src_tmp, src, align_num_bytes);
|
||||
for (i = 0; i < align_num_bytes / 4; i++)
|
||||
dst_tmp[i] = le32_to_cpu(src_tmp[i]);
|
||||
memcpy(dst, dst_tmp, num_bytes);
|
||||
}
|
||||
#else
|
||||
memcpy(dst, src, num_bytes);
|
||||
|
||||
@@ -252,7 +252,6 @@ static int radeonfb_create(struct drm_fb_helper *helper,
|
||||
}
|
||||
|
||||
info->par = rfbdev;
|
||||
info->skip_vt_switch = true;
|
||||
|
||||
ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
|
||||
if (ret) {
|
||||
|
||||
@@ -172,7 +172,7 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
|
||||
ret = sun4i_backend_drm_format_to_layer(plane, fb->pixel_format, &val);
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("Invalid format\n");
|
||||
return val;
|
||||
return ret;
|
||||
}
|
||||
|
||||
regmap_update_bits(backend->regs, SUN4I_BACKEND_ATTCTL_REG1(layer),
|
||||
|
||||
@@ -473,6 +473,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
|
||||
INIT_LIST_HEAD(&fbo->lru);
|
||||
INIT_LIST_HEAD(&fbo->swap);
|
||||
INIT_LIST_HEAD(&fbo->io_reserve_lru);
|
||||
mutex_init(&fbo->wu_mutex);
|
||||
fbo->moving = NULL;
|
||||
drm_vma_node_reset(&fbo->vma_node);
|
||||
atomic_set(&fbo->cpu_writers, 0);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -45,6 +46,7 @@ static const unsigned short normal_i2c[] = {
|
||||
#define JC42_REG_TEMP 0x05
|
||||
#define JC42_REG_MANID 0x06
|
||||
#define JC42_REG_DEVICEID 0x07
|
||||
#define JC42_REG_SMBUS 0x22 /* NXP and Atmel, possibly others? */
|
||||
|
||||
/* Status bits in temperature register */
|
||||
#define JC42_ALARM_CRIT_BIT 15
|
||||
@@ -73,6 +75,9 @@ static const unsigned short normal_i2c[] = {
|
||||
#define ONS_MANID 0x1b09 /* ON Semiconductor */
|
||||
#define STM_MANID 0x104a /* ST Microelectronics */
|
||||
|
||||
/* SMBUS register */
|
||||
#define SMBUS_STMOUT BIT(7) /* SMBus time-out, active low */
|
||||
|
||||
/* Supported chips */
|
||||
|
||||
/* Analog Devices */
|
||||
@@ -476,6 +481,22 @@ static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
|
||||
data->extended = !!(cap & JC42_CAP_RANGE);
|
||||
|
||||
if (device_property_read_bool(dev, "smbus-timeout-disable")) {
|
||||
int smbus;
|
||||
|
||||
/*
|
||||
* Not all chips support this register, but from a
|
||||
* quick read of various datasheets no chip appears
|
||||
* incompatible with the below attempt to disable
|
||||
* the timeout. And the whole thing is opt-in...
|
||||
*/
|
||||
smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS);
|
||||
if (smbus < 0)
|
||||
return smbus;
|
||||
i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS,
|
||||
smbus | SMBUS_STMOUT);
|
||||
}
|
||||
|
||||
config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG);
|
||||
if (config < 0)
|
||||
return config;
|
||||
|
||||
@@ -1592,6 +1592,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
/* Default timeout in interrupt mode: 200 ms */
|
||||
priv->adapter.timeout = HZ / 5;
|
||||
|
||||
if (dev->irq == IRQ_NOTCONNECTED)
|
||||
priv->features &= ~FEATURE_IRQ;
|
||||
|
||||
if (priv->features & FEATURE_IRQ) {
|
||||
u16 pcictl, pcists;
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ static int cm3232_reg_init(struct cm3232_chip *chip)
|
||||
if (ret < 0)
|
||||
dev_err(&chip->client->dev, "Error writing reg_cmd\n");
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -648,12 +648,19 @@ static void srp_path_rec_completion(int status,
|
||||
static int srp_lookup_path(struct srp_rdma_ch *ch)
|
||||
{
|
||||
struct srp_target_port *target = ch->target;
|
||||
int ret;
|
||||
int ret = -ENODEV;
|
||||
|
||||
ch->path.numb_path = 1;
|
||||
|
||||
init_completion(&ch->done);
|
||||
|
||||
/*
|
||||
* Avoid that the SCSI host can be removed by srp_remove_target()
|
||||
* before srp_path_rec_completion() is called.
|
||||
*/
|
||||
if (!scsi_host_get(target->scsi_host))
|
||||
goto out;
|
||||
|
||||
ch->path_query_id = ib_sa_path_rec_get(&srp_sa_client,
|
||||
target->srp_host->srp_dev->dev,
|
||||
target->srp_host->port,
|
||||
@@ -667,18 +674,24 @@ static int srp_lookup_path(struct srp_rdma_ch *ch)
|
||||
GFP_KERNEL,
|
||||
srp_path_rec_completion,
|
||||
ch, &ch->path_query);
|
||||
if (ch->path_query_id < 0)
|
||||
return ch->path_query_id;
|
||||
ret = ch->path_query_id;
|
||||
if (ret < 0)
|
||||
goto put;
|
||||
|
||||
ret = wait_for_completion_interruptible(&ch->done);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto put;
|
||||
|
||||
if (ch->status < 0)
|
||||
ret = ch->status;
|
||||
if (ret < 0)
|
||||
shost_printk(KERN_WARNING, target->scsi_host,
|
||||
PFX "Path record query failed\n");
|
||||
|
||||
return ch->status;
|
||||
put:
|
||||
scsi_host_put(target->scsi_host);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int srp_send_req(struct srp_rdma_ch *ch, bool multich)
|
||||
|
||||
@@ -2750,7 +2750,7 @@ static int srpt_parse_i_port_id(u8 i_port_id[16], const char *name)
|
||||
{
|
||||
const char *p;
|
||||
unsigned len, count, leading_zero_bytes;
|
||||
int ret, rc;
|
||||
int ret;
|
||||
|
||||
p = name;
|
||||
if (strncasecmp(p, "0x", 2) == 0)
|
||||
@@ -2762,10 +2762,9 @@ static int srpt_parse_i_port_id(u8 i_port_id[16], const char *name)
|
||||
count = min(len / 2, 16U);
|
||||
leading_zero_bytes = 16 - count;
|
||||
memset(i_port_id, 0, leading_zero_bytes);
|
||||
rc = hex2bin(i_port_id + leading_zero_bytes, p, count);
|
||||
if (rc < 0)
|
||||
pr_debug("hex2bin failed for srpt_parse_i_port_id: %d\n", rc);
|
||||
ret = 0;
|
||||
ret = hex2bin(i_port_id + leading_zero_bytes, p, count);
|
||||
if (ret < 0)
|
||||
pr_debug("hex2bin failed for srpt_parse_i_port_id: %d\n", ret);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1022,18 +1022,18 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
|
||||
int nr_parts;
|
||||
struct partition_affinity *parts;
|
||||
|
||||
parts_node = of_find_node_by_name(gic_node, "ppi-partitions");
|
||||
parts_node = of_get_child_by_name(gic_node, "ppi-partitions");
|
||||
if (!parts_node)
|
||||
return;
|
||||
|
||||
nr_parts = of_get_child_count(parts_node);
|
||||
|
||||
if (!nr_parts)
|
||||
return;
|
||||
goto out_put_node;
|
||||
|
||||
parts = kzalloc(sizeof(*parts) * nr_parts, GFP_KERNEL);
|
||||
if (WARN_ON(!parts))
|
||||
return;
|
||||
goto out_put_node;
|
||||
|
||||
for_each_child_of_node(parts_node, child_part) {
|
||||
struct partition_affinity *part;
|
||||
@@ -1100,6 +1100,9 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
|
||||
|
||||
gic_data.ppi_descs[i] = desc;
|
||||
}
|
||||
|
||||
out_put_node:
|
||||
of_node_put(parts_node);
|
||||
}
|
||||
|
||||
static void __init gic_of_setup_kvm_info(struct device_node *node)
|
||||
|
||||
@@ -404,6 +404,7 @@ long bch_bucket_alloc(struct cache *ca, unsigned reserve, bool wait)
|
||||
|
||||
finish_wait(&ca->set->bucket_wait, &w);
|
||||
out:
|
||||
if (ca->alloc_thread)
|
||||
wake_up_process(ca->alloc_thread);
|
||||
|
||||
trace_bcache_alloc(ca, reserve);
|
||||
@@ -476,7 +477,7 @@ int __bch_bucket_alloc_set(struct cache_set *c, unsigned reserve,
|
||||
if (b == -1)
|
||||
goto err;
|
||||
|
||||
k->ptr[i] = PTR(ca->buckets[b].gen,
|
||||
k->ptr[i] = MAKE_PTR(ca->buckets[b].gen,
|
||||
bucket_to_sector(c, b),
|
||||
ca->sb.nr_this_dev);
|
||||
|
||||
|
||||
@@ -584,7 +584,7 @@ static bool bch_extent_merge(struct btree_keys *bk, struct bkey *l, struct bkey
|
||||
return false;
|
||||
|
||||
for (i = 0; i < KEY_PTRS(l); i++)
|
||||
if (l->ptr[i] + PTR(0, KEY_SIZE(l), 0) != r->ptr[i] ||
|
||||
if (l->ptr[i] + MAKE_PTR(0, KEY_SIZE(l), 0) != r->ptr[i] ||
|
||||
PTR_BUCKET_NR(b->c, l, i) != PTR_BUCKET_NR(b->c, r, i))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -508,7 +508,7 @@ static void journal_reclaim(struct cache_set *c)
|
||||
continue;
|
||||
|
||||
ja->cur_idx = next;
|
||||
k->ptr[n++] = PTR(0,
|
||||
k->ptr[n++] = MAKE_PTR(0,
|
||||
bucket_to_sector(c, ca->sb.d[ja->cur_idx]),
|
||||
ca->sb.nr_this_dev);
|
||||
}
|
||||
|
||||
@@ -937,7 +937,8 @@ static void __get_memory_limit(struct dm_bufio_client *c,
|
||||
buffers = c->minimum_buffers;
|
||||
|
||||
*limit_buffers = buffers;
|
||||
*threshold_buffers = buffers * DM_BUFIO_WRITEBACK_PERCENT / 100;
|
||||
*threshold_buffers = mult_frac(buffers,
|
||||
DM_BUFIO_WRITEBACK_PERCENT, 100);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1856,19 +1857,15 @@ static int __init dm_bufio_init(void)
|
||||
memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches);
|
||||
memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names);
|
||||
|
||||
mem = (__u64)((totalram_pages - totalhigh_pages) *
|
||||
DM_BUFIO_MEMORY_PERCENT / 100) << PAGE_SHIFT;
|
||||
mem = (__u64)mult_frac(totalram_pages - totalhigh_pages,
|
||||
DM_BUFIO_MEMORY_PERCENT, 100) << PAGE_SHIFT;
|
||||
|
||||
if (mem > ULONG_MAX)
|
||||
mem = ULONG_MAX;
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
/*
|
||||
* Get the size of vmalloc space the same way as VMALLOC_TOTAL
|
||||
* in fs/proc/internal.h
|
||||
*/
|
||||
if (mem > (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100)
|
||||
mem = (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100;
|
||||
if (mem > mult_frac(VMALLOC_TOTAL, DM_BUFIO_VMALLOC_PERCENT, 100))
|
||||
mem = mult_frac(VMALLOC_TOTAL, DM_BUFIO_VMALLOC_PERCENT, 100);
|
||||
#endif
|
||||
|
||||
dm_bufio_default_cache_size = mem;
|
||||
|
||||
@@ -29,7 +29,6 @@ struct dm_kobject_holder {
|
||||
* DM targets must _not_ deference a mapped_device to directly access its members!
|
||||
*/
|
||||
struct mapped_device {
|
||||
struct srcu_struct io_barrier;
|
||||
struct mutex suspend_lock;
|
||||
|
||||
/*
|
||||
@@ -127,6 +126,8 @@ struct mapped_device {
|
||||
struct blk_mq_tag_set *tag_set;
|
||||
bool use_blk_mq:1;
|
||||
bool init_tio_pdu:1;
|
||||
|
||||
struct srcu_struct io_barrier;
|
||||
};
|
||||
|
||||
void dm_init_md_queue(struct mapped_device *md);
|
||||
|
||||
+12
-7
@@ -21,6 +21,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/pr.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#define DM_MSG_PREFIX "core"
|
||||
|
||||
@@ -1511,7 +1512,7 @@ static struct mapped_device *alloc_dev(int minor)
|
||||
struct mapped_device *md;
|
||||
void *old_md;
|
||||
|
||||
md = kzalloc_node(sizeof(*md), GFP_KERNEL, numa_node_id);
|
||||
md = vzalloc_node(sizeof(*md), numa_node_id);
|
||||
if (!md) {
|
||||
DMWARN("unable to allocate device, out of memory.");
|
||||
return NULL;
|
||||
@@ -1605,7 +1606,7 @@ bad_io_barrier:
|
||||
bad_minor:
|
||||
module_put(THIS_MODULE);
|
||||
bad_module_get:
|
||||
kfree(md);
|
||||
kvfree(md);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1624,7 +1625,7 @@ static void free_dev(struct mapped_device *md)
|
||||
free_minor(minor);
|
||||
|
||||
module_put(THIS_MODULE);
|
||||
kfree(md);
|
||||
kvfree(md);
|
||||
}
|
||||
|
||||
static void __bind_mempools(struct mapped_device *md, struct dm_table *t)
|
||||
@@ -2514,11 +2515,15 @@ struct mapped_device *dm_get_from_kobject(struct kobject *kobj)
|
||||
|
||||
md = container_of(kobj, struct mapped_device, kobj_holder.kobj);
|
||||
|
||||
if (test_bit(DMF_FREEING, &md->flags) ||
|
||||
dm_deleting_md(md))
|
||||
return NULL;
|
||||
|
||||
spin_lock(&_minor_lock);
|
||||
if (test_bit(DMF_FREEING, &md->flags) || dm_deleting_md(md)) {
|
||||
md = NULL;
|
||||
goto out;
|
||||
}
|
||||
dm_get(md);
|
||||
out:
|
||||
spin_unlock(&_minor_lock);
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,10 +286,13 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
|
||||
if (!dev->max_timeout)
|
||||
return -ENOSYS;
|
||||
|
||||
/* Check for multiply overflow */
|
||||
if (val > U32_MAX / 1000)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = val * 1000;
|
||||
|
||||
if (tmp < dev->min_timeout ||
|
||||
tmp > dev->max_timeout)
|
||||
if (tmp < dev->min_timeout || tmp > dev->max_timeout)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->s_timeout)
|
||||
|
||||
@@ -101,18 +101,23 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
|
||||
unsigned char *cmd,
|
||||
const struct firmware *firmware) {
|
||||
|
||||
struct as10x_fw_pkt_t fw_pkt;
|
||||
struct as10x_fw_pkt_t *fw_pkt;
|
||||
int total_read_bytes = 0, errno = 0;
|
||||
unsigned char addr_has_changed = 0;
|
||||
|
||||
fw_pkt = kmalloc(sizeof(*fw_pkt), GFP_KERNEL);
|
||||
if (!fw_pkt)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
|
||||
int read_bytes = 0, data_len = 0;
|
||||
|
||||
/* parse intel hex line */
|
||||
read_bytes = parse_hex_line(
|
||||
(u8 *) (firmware->data + total_read_bytes),
|
||||
fw_pkt.raw.address,
|
||||
fw_pkt.raw.data,
|
||||
fw_pkt->raw.address,
|
||||
fw_pkt->raw.data,
|
||||
&data_len,
|
||||
&addr_has_changed);
|
||||
|
||||
@@ -122,28 +127,28 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
|
||||
/* detect the end of file */
|
||||
total_read_bytes += read_bytes;
|
||||
if (total_read_bytes == firmware->size) {
|
||||
fw_pkt.u.request[0] = 0x00;
|
||||
fw_pkt.u.request[1] = 0x03;
|
||||
fw_pkt->u.request[0] = 0x00;
|
||||
fw_pkt->u.request[1] = 0x03;
|
||||
|
||||
/* send EOF command */
|
||||
errno = bus_adap->ops->upload_fw_pkt(bus_adap,
|
||||
(uint8_t *)
|
||||
&fw_pkt, 2, 0);
|
||||
fw_pkt, 2, 0);
|
||||
if (errno < 0)
|
||||
goto error;
|
||||
} else {
|
||||
if (!addr_has_changed) {
|
||||
/* prepare command to send */
|
||||
fw_pkt.u.request[0] = 0x00;
|
||||
fw_pkt.u.request[1] = 0x01;
|
||||
fw_pkt->u.request[0] = 0x00;
|
||||
fw_pkt->u.request[1] = 0x01;
|
||||
|
||||
data_len += sizeof(fw_pkt.u.request);
|
||||
data_len += sizeof(fw_pkt.raw.address);
|
||||
data_len += sizeof(fw_pkt->u.request);
|
||||
data_len += sizeof(fw_pkt->raw.address);
|
||||
|
||||
/* send cmd to device */
|
||||
errno = bus_adap->ops->upload_fw_pkt(bus_adap,
|
||||
(uint8_t *)
|
||||
&fw_pkt,
|
||||
fw_pkt,
|
||||
data_len,
|
||||
0);
|
||||
if (errno < 0)
|
||||
@@ -152,6 +157,7 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
|
||||
}
|
||||
}
|
||||
error:
|
||||
kfree(fw_pkt);
|
||||
return (errno == 0) ? total_read_bytes : errno;
|
||||
}
|
||||
|
||||
|
||||
@@ -1622,7 +1622,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
|
||||
nr = dev->devno;
|
||||
|
||||
assoc_desc = udev->actconfig->intf_assoc[0];
|
||||
if (assoc_desc->bFirstInterface != ifnum) {
|
||||
if (!assoc_desc || assoc_desc->bFirstInterface != ifnum) {
|
||||
dev_err(d, "Not found matching IAD interface\n");
|
||||
retval = -ENODEV;
|
||||
goto err_if;
|
||||
|
||||
@@ -1219,6 +1219,16 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_fill);
|
||||
|
||||
static u32 user_flags(const struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
u32 flags = ctrl->flags;
|
||||
|
||||
if (ctrl->is_ptr)
|
||||
flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes)
|
||||
{
|
||||
memset(ev->reserved, 0, sizeof(ev->reserved));
|
||||
@@ -1226,7 +1236,7 @@ static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 change
|
||||
ev->id = ctrl->id;
|
||||
ev->u.ctrl.changes = changes;
|
||||
ev->u.ctrl.type = ctrl->type;
|
||||
ev->u.ctrl.flags = ctrl->flags;
|
||||
ev->u.ctrl.flags = user_flags(ctrl);
|
||||
if (ctrl->is_ptr)
|
||||
ev->u.ctrl.value64 = 0;
|
||||
else
|
||||
@@ -2550,10 +2560,8 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctr
|
||||
else
|
||||
qc->id = ctrl->id;
|
||||
strlcpy(qc->name, ctrl->name, sizeof(qc->name));
|
||||
qc->flags = ctrl->flags;
|
||||
qc->flags = user_flags(ctrl);
|
||||
qc->type = ctrl->type;
|
||||
if (ctrl->is_ptr)
|
||||
qc->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD;
|
||||
qc->elem_size = ctrl->elem_size;
|
||||
qc->elems = ctrl->elems;
|
||||
qc->nr_of_dims = ctrl->nr_of_dims;
|
||||
|
||||
@@ -701,6 +701,7 @@ static struct twl4030_ins omap3_wrst_seq[] = {
|
||||
TWL_RESOURCE_RESET(RES_MAIN_REF),
|
||||
TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2),
|
||||
TWL_RESOURCE_RESET(RES_VUSB_3V1),
|
||||
TWL_RESOURCE_RESET(RES_VMMC1),
|
||||
TWL_RESOURCE_GROUP_RESET(RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1),
|
||||
TWL_RESOURCE_GROUP_RESET(RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0),
|
||||
TWL_RESOURCE_ON(RES_RESET),
|
||||
|
||||
@@ -365,7 +365,8 @@ static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf,
|
||||
memset(msg, 0, sizeof(msg));
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].buf = addrbuf;
|
||||
addrbuf[0] = 0x90 + offset;
|
||||
/* EUI-48 starts from 0x9a, EUI-64 from 0x98 */
|
||||
addrbuf[0] = 0xa0 - at24->chip.byte_len + offset;
|
||||
msg[0].len = 1;
|
||||
msg[1].addr = client->addr;
|
||||
msg[1].flags = I2C_M_RD;
|
||||
@@ -506,6 +507,9 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count)
|
||||
if (unlikely(!count))
|
||||
return count;
|
||||
|
||||
if (off + count > at24->chip.byte_len)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Read data from chip, protecting against concurrent updates
|
||||
* from this host, but not from other I2C masters.
|
||||
@@ -538,6 +542,9 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
|
||||
if (unlikely(!count))
|
||||
return -EINVAL;
|
||||
|
||||
if (off + count > at24->chip.byte_len)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Write data to chip, protecting against concurrent updates
|
||||
* from this host, but not from other I2C masters.
|
||||
@@ -638,6 +645,16 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
dev_warn(&client->dev,
|
||||
"page_size looks suspicious (no power of 2)!\n");
|
||||
|
||||
/*
|
||||
* REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while
|
||||
* the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4.
|
||||
*
|
||||
* Eventually we'll get rid of the magic values altoghether in favor of
|
||||
* real structs, but for now just manually set the right size.
|
||||
*/
|
||||
if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4)
|
||||
chip.byte_len = 6;
|
||||
|
||||
/* Use I2C operations unless we're stuck with SMBus extensions. */
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
if (chip.flags & AT24_FLAG_ADDR16)
|
||||
|
||||
@@ -155,6 +155,9 @@ static int mmc_bus_suspend(struct device *dev)
|
||||
return ret;
|
||||
|
||||
ret = host->bus_ops->suspend(host);
|
||||
if (ret)
|
||||
pm_generic_resume(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -763,7 +763,7 @@ MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
|
||||
MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
|
||||
MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
|
||||
MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
|
||||
MMC_DEV_ATTR(ocr, "%08x\n", card->ocr);
|
||||
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
|
||||
|
||||
static ssize_t mmc_fwrev_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
|
||||
@@ -683,7 +683,7 @@ MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
|
||||
MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
|
||||
MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
|
||||
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
|
||||
MMC_DEV_ATTR(ocr, "%08x\n", card->ocr);
|
||||
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
|
||||
|
||||
|
||||
static ssize_t mmc_dsr_show(struct device *dev,
|
||||
|
||||
@@ -116,6 +116,11 @@ static irqreturn_t mtk_ecc_irq(int irq, void *id)
|
||||
op = ECC_DECODE;
|
||||
dec = readw(ecc->regs + ECC_DECDONE);
|
||||
if (dec & ecc->sectors) {
|
||||
/*
|
||||
* Clear decode IRQ status once again to ensure that
|
||||
* there will be no extra IRQ.
|
||||
*/
|
||||
readw(ecc->regs + ECC_DECIRQ_STA);
|
||||
ecc->sectors = 0;
|
||||
complete(&ecc->done);
|
||||
} else {
|
||||
@@ -131,8 +136,6 @@ static irqreturn_t mtk_ecc_irq(int irq, void *id)
|
||||
}
|
||||
}
|
||||
|
||||
writel(0, ecc->regs + ECC_IRQ_REG(op));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -342,6 +345,12 @@ void mtk_ecc_disable(struct mtk_ecc *ecc)
|
||||
|
||||
/* disable it */
|
||||
mtk_ecc_wait_idle(ecc, op);
|
||||
if (op == ECC_DECODE)
|
||||
/*
|
||||
* Clear decode IRQ status in case there is a timeout to wait
|
||||
* decode IRQ.
|
||||
*/
|
||||
readw(ecc->regs + ECC_DECIRQ_STA);
|
||||
writew(0, ecc->regs + ECC_IRQ_REG(op));
|
||||
writew(ECC_OP_DISABLE, ecc->regs + ECC_CTL_REG(op));
|
||||
|
||||
|
||||
@@ -2935,15 +2935,18 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const uint8_t *buf)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
int chipnr = (int)(to >> chip->chip_shift);
|
||||
struct mtd_oob_ops ops;
|
||||
int ret;
|
||||
|
||||
/* Wait for the device to get ready */
|
||||
panic_nand_wait(mtd, chip, 400);
|
||||
|
||||
/* Grab the device */
|
||||
panic_nand_get_device(chip, mtd, FL_WRITING);
|
||||
|
||||
chip->select_chip(mtd, chipnr);
|
||||
|
||||
/* Wait for the device to get ready */
|
||||
panic_nand_wait(mtd, chip, 400);
|
||||
|
||||
memset(&ops, 0, sizeof(ops));
|
||||
ops.len = len;
|
||||
ops.datbuf = (uint8_t *)buf;
|
||||
|
||||
+126
-17
@@ -1133,26 +1133,26 @@ static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
|
||||
0x97, 0x79, 0xe5, 0x24, 0xb5};
|
||||
|
||||
/**
|
||||
* omap_calculate_ecc_bch - Generate bytes of ECC bytes
|
||||
* _omap_calculate_ecc_bch - Generate ECC bytes for one sector
|
||||
* @mtd: MTD device structure
|
||||
* @dat: The pointer to data on which ecc is computed
|
||||
* @ecc_code: The ecc_code buffer
|
||||
* @i: The sector number (for a multi sector page)
|
||||
*
|
||||
* Support calculating of BCH4/8 ecc vectors for the page
|
||||
* Support calculating of BCH4/8/16 ECC vectors for one sector
|
||||
* within a page. Sector number is in @i.
|
||||
*/
|
||||
static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
|
||||
const u_char *dat, u_char *ecc_calc)
|
||||
static int _omap_calculate_ecc_bch(struct mtd_info *mtd,
|
||||
const u_char *dat, u_char *ecc_calc, int i)
|
||||
{
|
||||
struct omap_nand_info *info = mtd_to_omap(mtd);
|
||||
int eccbytes = info->nand.ecc.bytes;
|
||||
struct gpmc_nand_regs *gpmc_regs = &info->reg;
|
||||
u8 *ecc_code;
|
||||
unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4;
|
||||
unsigned long bch_val1, bch_val2, bch_val3, bch_val4;
|
||||
u32 val;
|
||||
int i, j;
|
||||
int j;
|
||||
|
||||
nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
|
||||
for (i = 0; i < nsectors; i++) {
|
||||
ecc_code = ecc_calc;
|
||||
switch (info->ecc_opt) {
|
||||
case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
|
||||
@@ -1231,7 +1231,8 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
|
||||
switch (info->ecc_opt) {
|
||||
case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
|
||||
/* Add constant polynomial to remainder, so that
|
||||
* ECC of blank pages results in 0x0 on reading back */
|
||||
* ECC of blank pages results in 0x0 on reading back
|
||||
*/
|
||||
for (j = 0; j < eccbytes; j++)
|
||||
ecc_calc[j] ^= bch4_polynomial[j];
|
||||
break;
|
||||
@@ -1241,7 +1242,8 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
|
||||
break;
|
||||
case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
|
||||
/* Add constant polynomial to remainder, so that
|
||||
* ECC of blank pages results in 0x0 on reading back */
|
||||
* ECC of blank pages results in 0x0 on reading back
|
||||
*/
|
||||
for (j = 0; j < eccbytes; j++)
|
||||
ecc_calc[j] ^= bch8_polynomial[j];
|
||||
break;
|
||||
@@ -1255,6 +1257,47 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_calculate_ecc_bch_sw - ECC generator for sector for SW based correction
|
||||
* @mtd: MTD device structure
|
||||
* @dat: The pointer to data on which ecc is computed
|
||||
* @ecc_code: The ecc_code buffer
|
||||
*
|
||||
* Support calculating of BCH4/8/16 ECC vectors for one sector. This is used
|
||||
* when SW based correction is required as ECC is required for one sector
|
||||
* at a time.
|
||||
*/
|
||||
static int omap_calculate_ecc_bch_sw(struct mtd_info *mtd,
|
||||
const u_char *dat, u_char *ecc_calc)
|
||||
{
|
||||
return _omap_calculate_ecc_bch(mtd, dat, ecc_calc, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_calculate_ecc_bch_multi - Generate ECC for multiple sectors
|
||||
* @mtd: MTD device structure
|
||||
* @dat: The pointer to data on which ecc is computed
|
||||
* @ecc_code: The ecc_code buffer
|
||||
*
|
||||
* Support calculating of BCH4/8/16 ecc vectors for the entire page in one go.
|
||||
*/
|
||||
static int omap_calculate_ecc_bch_multi(struct mtd_info *mtd,
|
||||
const u_char *dat, u_char *ecc_calc)
|
||||
{
|
||||
struct omap_nand_info *info = mtd_to_omap(mtd);
|
||||
int eccbytes = info->nand.ecc.bytes;
|
||||
unsigned long nsectors;
|
||||
int i, ret;
|
||||
|
||||
nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
|
||||
for (i = 0; i < nsectors; i++) {
|
||||
ret = _omap_calculate_ecc_bch(mtd, dat, ecc_calc, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ecc_calc += eccbytes;
|
||||
}
|
||||
|
||||
@@ -1496,7 +1539,7 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
chip->write_buf(mtd, buf, mtd->writesize);
|
||||
|
||||
/* Update ecc vector from GPMC result registers */
|
||||
chip->ecc.calculate(mtd, buf, &ecc_calc[0]);
|
||||
omap_calculate_ecc_bch_multi(mtd, buf, &ecc_calc[0]);
|
||||
|
||||
ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
|
||||
chip->ecc.total);
|
||||
@@ -1508,6 +1551,72 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_write_subpage_bch - BCH hardware ECC based subpage write
|
||||
* @mtd: mtd info structure
|
||||
* @chip: nand chip info structure
|
||||
* @offset: column address of subpage within the page
|
||||
* @data_len: data length
|
||||
* @buf: data buffer
|
||||
* @oob_required: must write chip->oob_poi to OOB
|
||||
* @page: page number to write
|
||||
*
|
||||
* OMAP optimized subpage write method.
|
||||
*/
|
||||
static int omap_write_subpage_bch(struct mtd_info *mtd,
|
||||
struct nand_chip *chip, u32 offset,
|
||||
u32 data_len, const u8 *buf,
|
||||
int oob_required, int page)
|
||||
{
|
||||
u8 *ecc_calc = chip->buffers->ecccalc;
|
||||
int ecc_size = chip->ecc.size;
|
||||
int ecc_bytes = chip->ecc.bytes;
|
||||
int ecc_steps = chip->ecc.steps;
|
||||
u32 start_step = offset / ecc_size;
|
||||
u32 end_step = (offset + data_len - 1) / ecc_size;
|
||||
int step, ret = 0;
|
||||
|
||||
/*
|
||||
* Write entire page at one go as it would be optimal
|
||||
* as ECC is calculated by hardware.
|
||||
* ECC is calculated for all subpages but we choose
|
||||
* only what we want.
|
||||
*/
|
||||
|
||||
/* Enable GPMC ECC engine */
|
||||
chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
|
||||
|
||||
/* Write data */
|
||||
chip->write_buf(mtd, buf, mtd->writesize);
|
||||
|
||||
for (step = 0; step < ecc_steps; step++) {
|
||||
/* mask ECC of un-touched subpages by padding 0xFF */
|
||||
if (step < start_step || step > end_step)
|
||||
memset(ecc_calc, 0xff, ecc_bytes);
|
||||
else
|
||||
ret = _omap_calculate_ecc_bch(mtd, buf, ecc_calc, step);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf += ecc_size;
|
||||
ecc_calc += ecc_bytes;
|
||||
}
|
||||
|
||||
/* copy calculated ECC for whole page to chip->buffer->oob */
|
||||
/* this include masked-value(0xFF) for unwritten subpages */
|
||||
ecc_calc = chip->buffers->ecccalc;
|
||||
ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
|
||||
chip->ecc.total);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* write OOB buffer to NAND device */
|
||||
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_read_page_bch - BCH ecc based page read function for entire page
|
||||
* @mtd: mtd info structure
|
||||
@@ -1544,7 +1653,7 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
chip->ecc.total);
|
||||
|
||||
/* Calculate ecc bytes */
|
||||
chip->ecc.calculate(mtd, buf, ecc_calc);
|
||||
omap_calculate_ecc_bch_multi(mtd, buf, ecc_calc);
|
||||
|
||||
ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
|
||||
chip->ecc.total);
|
||||
@@ -2044,7 +2153,7 @@ static int omap_nand_probe(struct platform_device *pdev)
|
||||
nand_chip->ecc.strength = 4;
|
||||
nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
|
||||
nand_chip->ecc.correct = nand_bch_correct_data;
|
||||
nand_chip->ecc.calculate = omap_calculate_ecc_bch;
|
||||
nand_chip->ecc.calculate = omap_calculate_ecc_bch_sw;
|
||||
mtd_set_ooblayout(mtd, &omap_sw_ooblayout_ops);
|
||||
/* Reserve one byte for the OMAP marker */
|
||||
oobbytes_per_step = nand_chip->ecc.bytes + 1;
|
||||
@@ -2066,9 +2175,9 @@ static int omap_nand_probe(struct platform_device *pdev)
|
||||
nand_chip->ecc.strength = 4;
|
||||
nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
|
||||
nand_chip->ecc.correct = omap_elm_correct_data;
|
||||
nand_chip->ecc.calculate = omap_calculate_ecc_bch;
|
||||
nand_chip->ecc.read_page = omap_read_page_bch;
|
||||
nand_chip->ecc.write_page = omap_write_page_bch;
|
||||
nand_chip->ecc.write_subpage = omap_write_subpage_bch;
|
||||
mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
|
||||
oobbytes_per_step = nand_chip->ecc.bytes;
|
||||
|
||||
@@ -2087,7 +2196,7 @@ static int omap_nand_probe(struct platform_device *pdev)
|
||||
nand_chip->ecc.strength = 8;
|
||||
nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
|
||||
nand_chip->ecc.correct = nand_bch_correct_data;
|
||||
nand_chip->ecc.calculate = omap_calculate_ecc_bch;
|
||||
nand_chip->ecc.calculate = omap_calculate_ecc_bch_sw;
|
||||
mtd_set_ooblayout(mtd, &omap_sw_ooblayout_ops);
|
||||
/* Reserve one byte for the OMAP marker */
|
||||
oobbytes_per_step = nand_chip->ecc.bytes + 1;
|
||||
@@ -2109,9 +2218,9 @@ static int omap_nand_probe(struct platform_device *pdev)
|
||||
nand_chip->ecc.strength = 8;
|
||||
nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
|
||||
nand_chip->ecc.correct = omap_elm_correct_data;
|
||||
nand_chip->ecc.calculate = omap_calculate_ecc_bch;
|
||||
nand_chip->ecc.read_page = omap_read_page_bch;
|
||||
nand_chip->ecc.write_page = omap_write_page_bch;
|
||||
nand_chip->ecc.write_subpage = omap_write_subpage_bch;
|
||||
mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
|
||||
oobbytes_per_step = nand_chip->ecc.bytes;
|
||||
|
||||
@@ -2131,9 +2240,9 @@ static int omap_nand_probe(struct platform_device *pdev)
|
||||
nand_chip->ecc.strength = 16;
|
||||
nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
|
||||
nand_chip->ecc.correct = omap_elm_correct_data;
|
||||
nand_chip->ecc.calculate = omap_calculate_ecc_bch;
|
||||
nand_chip->ecc.read_page = omap_read_page_bch;
|
||||
nand_chip->ecc.write_page = omap_write_page_bch;
|
||||
nand_chip->ecc.write_subpage = omap_write_subpage_bch;
|
||||
mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
|
||||
oobbytes_per_step = nand_chip->ecc.bytes;
|
||||
|
||||
|
||||
@@ -2366,9 +2366,9 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
* 4) Get the hardware address.
|
||||
* 5) Put the card to sleep.
|
||||
*/
|
||||
if (typhoon_reset(ioaddr, WaitSleep) < 0) {
|
||||
err = typhoon_reset(ioaddr, WaitSleep);
|
||||
if (err < 0) {
|
||||
err_msg = "could not reset 3XP";
|
||||
err = -EIO;
|
||||
goto error_out_dma;
|
||||
}
|
||||
|
||||
@@ -2382,16 +2382,16 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
typhoon_init_interface(tp);
|
||||
typhoon_init_rings(tp);
|
||||
|
||||
if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
|
||||
err = typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST);
|
||||
if (err < 0) {
|
||||
err_msg = "cannot boot 3XP sleep image";
|
||||
err = -EIO;
|
||||
goto error_out_reset;
|
||||
}
|
||||
|
||||
INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS);
|
||||
if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) {
|
||||
err = typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp);
|
||||
if (err < 0) {
|
||||
err_msg = "cannot read MAC address";
|
||||
err = -EIO;
|
||||
goto error_out_reset;
|
||||
}
|
||||
|
||||
@@ -2400,6 +2400,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
||||
if (!is_valid_ether_addr(dev->dev_addr)) {
|
||||
err_msg = "Could not obtain valid ethernet address, aborting";
|
||||
err = -EIO;
|
||||
goto error_out_reset;
|
||||
}
|
||||
|
||||
@@ -2407,7 +2408,8 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
* later when we print out the version reported.
|
||||
*/
|
||||
INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
|
||||
if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
|
||||
err = typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp);
|
||||
if (err < 0) {
|
||||
err_msg = "Could not get Sleep Image version";
|
||||
goto error_out_reset;
|
||||
}
|
||||
@@ -2424,9 +2426,9 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if(xp_resp[0].numDesc != 0)
|
||||
tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET;
|
||||
|
||||
if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) {
|
||||
err = typhoon_sleep(tp, PCI_D3hot, 0);
|
||||
if (err < 0) {
|
||||
err_msg = "cannot put adapter to sleep";
|
||||
err = -EIO;
|
||||
goto error_out_reset;
|
||||
}
|
||||
|
||||
@@ -2449,7 +2451,8 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
dev->features = dev->hw_features |
|
||||
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM;
|
||||
|
||||
if(register_netdev(dev) < 0) {
|
||||
err = register_netdev(dev);
|
||||
if (err < 0) {
|
||||
err_msg = "unable to register netdev";
|
||||
goto error_out_reset;
|
||||
}
|
||||
|
||||
@@ -3800,6 +3800,30 @@ static int hwrm_ring_alloc_send_msg(struct bnxt *bp,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnxt_hwrm_set_async_event_cr(struct bnxt *bp, int idx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (BNXT_PF(bp)) {
|
||||
struct hwrm_func_cfg_input req = {0};
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
|
||||
req.fid = cpu_to_le16(0xffff);
|
||||
req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_ASYNC_EVENT_CR);
|
||||
req.async_event_cr = cpu_to_le16(idx);
|
||||
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
} else {
|
||||
struct hwrm_func_vf_cfg_input req = {0};
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_CFG, -1, -1);
|
||||
req.enables =
|
||||
cpu_to_le32(FUNC_VF_CFG_REQ_ENABLES_ASYNC_EVENT_CR);
|
||||
req.async_event_cr = cpu_to_le16(idx);
|
||||
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
|
||||
{
|
||||
int i, rc = 0;
|
||||
@@ -3816,6 +3840,12 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
|
||||
goto err_out;
|
||||
BNXT_CP_DB(cpr->cp_doorbell, cpr->cp_raw_cons);
|
||||
bp->grp_info[i].cp_fw_ring_id = ring->fw_ring_id;
|
||||
|
||||
if (!i) {
|
||||
rc = bnxt_hwrm_set_async_event_cr(bp, ring->fw_ring_id);
|
||||
if (rc)
|
||||
netdev_warn(bp->dev, "Failed to set async event completion ring.\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < bp->tx_nr_rings; i++) {
|
||||
|
||||
@@ -398,6 +398,7 @@
|
||||
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
|
||||
#define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */
|
||||
#define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */
|
||||
#define E1000_ICR_RXO 0x00000040 /* Receiver Overrun */
|
||||
#define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */
|
||||
#define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */
|
||||
/* If this bit asserted, the driver should claim the interrupt */
|
||||
|
||||
@@ -410,6 +410,9 @@ void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
|
||||
* Checks to see of the link status of the hardware has changed. If a
|
||||
* change in link status has been detected, then we read the PHY registers
|
||||
* to get the current speed/duplex if link exists.
|
||||
*
|
||||
* Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link
|
||||
* up).
|
||||
**/
|
||||
s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
|
||||
{
|
||||
@@ -423,7 +426,7 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
|
||||
* Change or Rx Sequence Error interrupt.
|
||||
*/
|
||||
if (!mac->get_link_status)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
/* First we want to see if the MII Status Register reports
|
||||
* link. If so, then we want to get the current speed/duplex
|
||||
@@ -461,12 +464,14 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
|
||||
* different link partner.
|
||||
*/
|
||||
ret_val = e1000e_config_fc_after_link_up(hw);
|
||||
if (ret_val)
|
||||
if (ret_val) {
|
||||
e_dbg("Error configuring flow control\n");
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000e_check_for_fiber_link - Check for link (Fiber)
|
||||
* @hw: pointer to the HW structure
|
||||
|
||||
@@ -1905,14 +1905,30 @@ static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
|
||||
struct net_device *netdev = data;
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 icr;
|
||||
bool enable = true;
|
||||
|
||||
hw->mac.get_link_status = true;
|
||||
|
||||
/* guard against interrupt when we're going down */
|
||||
if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
||||
mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
||||
ew32(IMS, E1000_IMS_OTHER);
|
||||
icr = er32(ICR);
|
||||
if (icr & E1000_ICR_RXO) {
|
||||
ew32(ICR, E1000_ICR_RXO);
|
||||
enable = false;
|
||||
/* napi poll will re-enable Other, make sure it runs */
|
||||
if (napi_schedule_prep(&adapter->napi)) {
|
||||
adapter->total_rx_bytes = 0;
|
||||
adapter->total_rx_packets = 0;
|
||||
__napi_schedule(&adapter->napi);
|
||||
}
|
||||
}
|
||||
if (icr & E1000_ICR_LSC) {
|
||||
ew32(ICR, E1000_ICR_LSC);
|
||||
hw->mac.get_link_status = true;
|
||||
/* guard against interrupt when we're going down */
|
||||
if (!test_bit(__E1000_DOWN, &adapter->state))
|
||||
mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
||||
}
|
||||
|
||||
if (enable && !test_bit(__E1000_DOWN, &adapter->state))
|
||||
ew32(IMS, E1000_IMS_OTHER);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -2683,7 +2699,8 @@ static int e1000e_poll(struct napi_struct *napi, int weight)
|
||||
napi_complete_done(napi, work_done);
|
||||
if (!test_bit(__E1000_DOWN, &adapter->state)) {
|
||||
if (adapter->msix_entries)
|
||||
ew32(IMS, adapter->rx_ring->ims_val);
|
||||
ew32(IMS, adapter->rx_ring->ims_val |
|
||||
E1000_IMS_OTHER);
|
||||
else
|
||||
e1000_irq_enable(adapter);
|
||||
}
|
||||
@@ -4178,7 +4195,7 @@ static void e1000e_trigger_lsc(struct e1000_adapter *adapter)
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
|
||||
if (adapter->msix_entries)
|
||||
ew32(ICS, E1000_ICS_OTHER);
|
||||
ew32(ICS, E1000_ICS_LSC | E1000_ICS_OTHER);
|
||||
else
|
||||
ew32(ICS, E1000_ICS_LSC);
|
||||
}
|
||||
@@ -5056,7 +5073,7 @@ static bool e1000e_has_link(struct e1000_adapter *adapter)
|
||||
case e1000_media_type_copper:
|
||||
if (hw->mac.get_link_status) {
|
||||
ret_val = hw->mac.ops.check_for_link(hw);
|
||||
link_active = !hw->mac.get_link_status;
|
||||
link_active = ret_val > 0;
|
||||
} else {
|
||||
link_active = true;
|
||||
}
|
||||
@@ -5074,7 +5091,7 @@ static bool e1000e_has_link(struct e1000_adapter *adapter)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
|
||||
if ((ret_val == -E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
|
||||
(er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
|
||||
/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
|
||||
e_info("Gigabit has been disabled, downgrading speed\n");
|
||||
|
||||
@@ -1744,6 +1744,7 @@ s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
|
||||
s32 ret_val = 0;
|
||||
u16 i, phy_status;
|
||||
|
||||
*success = false;
|
||||
for (i = 0; i < iterations; i++) {
|
||||
/* Some PHYs require the MII_BMSR register to be read
|
||||
* twice due to the link bit being sticky. No harm doing
|
||||
@@ -1763,16 +1764,16 @@ s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
|
||||
ret_val = e1e_rphy(hw, MII_BMSR, &phy_status);
|
||||
if (ret_val)
|
||||
break;
|
||||
if (phy_status & BMSR_LSTATUS)
|
||||
if (phy_status & BMSR_LSTATUS) {
|
||||
*success = true;
|
||||
break;
|
||||
}
|
||||
if (usec_interval >= 1000)
|
||||
msleep(usec_interval / 1000);
|
||||
else
|
||||
udelay(usec_interval);
|
||||
}
|
||||
|
||||
*success = (i < iterations);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
@@ -1225,7 +1225,7 @@ static bool fm10k_clean_tx_irq(struct fm10k_q_vector *q_vector,
|
||||
break;
|
||||
|
||||
/* prevent any other reads prior to eop_desc */
|
||||
read_barrier_depends();
|
||||
smp_rmb();
|
||||
|
||||
/* if DD is not set pending work has not been completed */
|
||||
if (!(eop_desc->flags & FM10K_TXD_FLAG_DONE))
|
||||
|
||||
@@ -3604,7 +3604,7 @@ static bool i40e_clean_fdir_tx_irq(struct i40e_ring *tx_ring, int budget)
|
||||
break;
|
||||
|
||||
/* prevent any other reads prior to eop_desc */
|
||||
read_barrier_depends();
|
||||
smp_rmb();
|
||||
|
||||
/* if the descriptor isn't done, no work yet to do */
|
||||
if (!(eop_desc->cmd_type_offset_bsz &
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user