mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-04 18:19:28 +09:00
Merge beff507e9e ("s390/cpum_sf: Remove WARN_ON_ONCE statements") into android14-6.1-lts
Steps on the way to 6.1.113 Resolves merge conflicts in: fs/erofs/fscache.c fs/erofs/inode.c fs/erofs/zdata.c kernel/sched/psi.c Change-Id: Icbb83e1d8d4b65f380f36046a6e98e341c53d77d Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -109,17 +109,17 @@ Get sum of delays, since system boot, for all pids with tgid 5::
|
||||
CPU count real total virtual total delay total delay average
|
||||
8 7000000 6872122 3382277 0.423ms
|
||||
IO count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
SWAP count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
RECLAIM count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
THRASHING count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
COMPACT count delay total delay average
|
||||
0 0 0ms
|
||||
WPCOPY count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
WPCOPY count delay total delay average
|
||||
0 0 0.000ms
|
||||
|
||||
Get IO accounting for pid 1, it works only with -p::
|
||||
|
||||
|
||||
@@ -4588,6 +4588,16 @@
|
||||
printk.time= Show timing data prefixed to each printk message line
|
||||
Format: <bool> (1/Y/y=enable, 0/N/n=disable)
|
||||
|
||||
proc_mem.force_override= [KNL]
|
||||
Format: {always | ptrace | never}
|
||||
Traditionally /proc/pid/mem allows memory permissions to be
|
||||
overridden without restrictions. This option may be set to
|
||||
restrict that. Can be one of:
|
||||
- 'always': traditional behavior always allows mem overrides.
|
||||
- 'ptrace': only allow mem overrides for active ptracers.
|
||||
- 'never': never allow mem overrides.
|
||||
If not specified, default is the CONFIG_PROC_MEM_* choice.
|
||||
|
||||
processor.max_cstate= [HW,ACPI]
|
||||
Limit processor to maximum C-state
|
||||
max_cstate=9 overrides any DMI blacklist limit.
|
||||
|
||||
@@ -130,6 +130,8 @@ stable kernels.
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
|
||||
@@ -166,6 +168,8 @@ stable kernels.
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
|
||||
|
||||
@@ -17,8 +17,9 @@ a) 等待一个CPU(任务为可运行)
|
||||
b) 完成由该任务发起的块I/O同步请求
|
||||
c) 页面交换
|
||||
d) 内存回收
|
||||
e) 页缓存抖动
|
||||
e) 抖动
|
||||
f) 直接规整
|
||||
g) 写保护复制
|
||||
|
||||
并将这些统计信息通过taskstats接口提供给用户空间。
|
||||
|
||||
@@ -42,7 +43,7 @@ f) 直接规整
|
||||
include/uapi/linux/taskstats.h
|
||||
|
||||
其描述了延时计数相关字段。系统通常以计数器形式返回 CPU、同步块 I/O、交换、内存
|
||||
回收、页缓存抖动、直接规整等的累积延时。
|
||||
回收、页缓存抖动、直接规整、写保护复制等的累积延时。
|
||||
|
||||
取任务某计数器两个连续读数的差值,将得到任务在该时间间隔内等待对应资源的总延时。
|
||||
|
||||
@@ -91,15 +92,17 @@ getdelays命令的一般格式::
|
||||
CPU count real total virtual total delay total delay average
|
||||
8 7000000 6872122 3382277 0.423ms
|
||||
IO count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
SWAP count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
RECLAIM count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
THRASHING count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
COMPACT count delay total delay average
|
||||
0 0 0ms
|
||||
0 0 0.000ms
|
||||
WPCOPY count delay total delay average
|
||||
0 0 0ms
|
||||
|
||||
获取pid为1的IO计数,它只和-p一起使用::
|
||||
# ./getdelays -i -p 1
|
||||
|
||||
@@ -711,7 +711,7 @@ static int __init aes_init(void)
|
||||
algname = aes_algs[i].base.cra_name + 2;
|
||||
drvname = aes_algs[i].base.cra_driver_name + 2;
|
||||
basename = aes_algs[i].base.cra_driver_name;
|
||||
simd = simd_skcipher_create_compat(algname, drvname, basename);
|
||||
simd = simd_skcipher_create_compat(aes_algs + i, algname, drvname, basename);
|
||||
err = PTR_ERR(simd);
|
||||
if (IS_ERR(simd))
|
||||
goto unregister_simds;
|
||||
|
||||
@@ -539,7 +539,7 @@ static int __init aes_init(void)
|
||||
algname = aes_algs[i].base.cra_name + 2;
|
||||
drvname = aes_algs[i].base.cra_driver_name + 2;
|
||||
basename = aes_algs[i].base.cra_driver_name;
|
||||
simd = simd_skcipher_create_compat(algname, drvname, basename);
|
||||
simd = simd_skcipher_create_compat(aes_algs + i, algname, drvname, basename);
|
||||
err = PTR_ERR(simd);
|
||||
if (IS_ERR(simd))
|
||||
goto unregister_simds;
|
||||
|
||||
@@ -999,6 +999,7 @@ config ARM64_ERRATUM_3194386
|
||||
* ARM Cortex-A78C erratum 3324346
|
||||
* ARM Cortex-A78C erratum 3324347
|
||||
* ARM Cortex-A710 erratam 3324338
|
||||
* ARM Cortex-A715 errartum 3456084
|
||||
* ARM Cortex-A720 erratum 3456091
|
||||
* ARM Cortex-A725 erratum 3456106
|
||||
* ARM Cortex-X1 erratum 3324344
|
||||
@@ -1009,6 +1010,7 @@ config ARM64_ERRATUM_3194386
|
||||
* ARM Cortex-X925 erratum 3324334
|
||||
* ARM Neoverse-N1 erratum 3324349
|
||||
* ARM Neoverse N2 erratum 3324339
|
||||
* ARM Neoverse-N3 erratum 3456111
|
||||
* ARM Neoverse-V1 erratum 3324341
|
||||
* ARM Neoverse V2 erratum 3324336
|
||||
* ARM Neoverse-V3 erratum 3312417
|
||||
|
||||
@@ -2125,7 +2125,7 @@
|
||||
"jedec,ufs-2.0";
|
||||
reg = <0 0x01d84000 0 0x3000>;
|
||||
interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
|
||||
phys = <&ufs_mem_phy>;
|
||||
phys = <&ufs_mem_phy_lanes>;
|
||||
phy-names = "ufsphy";
|
||||
lanes-per-direction = <2>;
|
||||
#reset-cells = <1>;
|
||||
@@ -2169,8 +2169,10 @@
|
||||
|
||||
ufs_mem_phy: phy@1d87000 {
|
||||
compatible = "qcom,sm8250-qmp-ufs-phy";
|
||||
reg = <0 0x01d87000 0 0x1000>;
|
||||
|
||||
reg = <0 0x01d87000 0 0x1c0>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
clock-names = "ref",
|
||||
"ref_aux";
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
@@ -2178,12 +2180,18 @@
|
||||
|
||||
resets = <&ufs_mem_hc 0>;
|
||||
reset-names = "ufsphy";
|
||||
status = "disabled";
|
||||
|
||||
power-domains = <&gcc UFS_PHY_GDSC>;
|
||||
|
||||
#phy-cells = <0>;
|
||||
|
||||
status = "disabled";
|
||||
ufs_mem_phy_lanes: phy@1d87400 {
|
||||
reg = <0 0x01d87400 0 0x16c>,
|
||||
<0 0x01d87600 0 0x200>,
|
||||
<0 0x01d87c00 0 0x200>,
|
||||
<0 0x01d87800 0 0x16c>,
|
||||
<0 0x01d87a00 0 0x200>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
ipa_virt: interconnect@1e00000 {
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#define ARM_CPU_PART_CORTEX_A510 0xD46
|
||||
#define ARM_CPU_PART_CORTEX_A520 0xD80
|
||||
#define ARM_CPU_PART_CORTEX_A710 0xD47
|
||||
#define ARM_CPU_PART_CORTEX_A715 0xD4D
|
||||
#define ARM_CPU_PART_CORTEX_X2 0xD48
|
||||
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
|
||||
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
|
||||
@@ -93,6 +94,7 @@
|
||||
#define ARM_CPU_PART_NEOVERSE_V3 0xD84
|
||||
#define ARM_CPU_PART_CORTEX_X925 0xD85
|
||||
#define ARM_CPU_PART_CORTEX_A725 0xD87
|
||||
#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
|
||||
|
||||
#define APM_CPU_PART_XGENE 0x000
|
||||
#define APM_CPU_VAR_POTENZA 0x00
|
||||
@@ -156,6 +158,7 @@
|
||||
#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
|
||||
#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520)
|
||||
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
|
||||
#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
|
||||
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
|
||||
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
|
||||
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
|
||||
@@ -167,6 +170,7 @@
|
||||
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
|
||||
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
|
||||
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
|
||||
#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
|
||||
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
|
||||
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
|
||||
|
||||
@@ -442,6 +442,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
|
||||
@@ -452,6 +453,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
|
||||
|
||||
@@ -82,7 +82,6 @@ CONFIG_ZSWAP=y
|
||||
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y
|
||||
CONFIG_ZPOOL=y
|
||||
CONFIG_ZBUD=y
|
||||
CONFIG_Z3FOLD=y
|
||||
CONFIG_ZSMALLOC=m
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
||||
@@ -1038,8 +1038,7 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
|
||||
STREG %r16, PT_ISR(%r29)
|
||||
STREG %r17, PT_IOR(%r29)
|
||||
|
||||
#if 0 && defined(CONFIG_64BIT)
|
||||
/* Revisit when we have 64-bit code above 4Gb */
|
||||
#if defined(CONFIG_64BIT)
|
||||
b,n intr_save2
|
||||
|
||||
skip_save_ior:
|
||||
@@ -1047,8 +1046,7 @@ skip_save_ior:
|
||||
* need to adjust iasq/iaoq here in the same way we adjusted isr/ior
|
||||
* above.
|
||||
*/
|
||||
extrd,u,* %r8,PSW_W_BIT,1,%r1
|
||||
cmpib,COND(=),n 1,%r1,intr_save2
|
||||
bb,COND(>=),n %r8,PSW_W_BIT,intr_save2
|
||||
LDREG PT_IASQ0(%r29), %r16
|
||||
LDREG PT_IAOQ0(%r29), %r17
|
||||
/* adjust iasq/iaoq */
|
||||
|
||||
@@ -232,10 +232,10 @@ linux_gateway_entry:
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
ldil L%sys_call_table, %r1
|
||||
or,= %r2,%r2,%r2
|
||||
addil L%(sys_call_table64-sys_call_table), %r1
|
||||
or,ev %r2,%r2,%r2
|
||||
ldil L%sys_call_table64, %r1
|
||||
ldo R%sys_call_table(%r1), %r19
|
||||
or,= %r2,%r2,%r2
|
||||
or,ev %r2,%r2,%r2
|
||||
ldo R%sys_call_table64(%r1), %r19
|
||||
#else
|
||||
load32 sys_call_table, %r19
|
||||
@@ -368,10 +368,10 @@ tracesys_next:
|
||||
extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */
|
||||
|
||||
ldil L%sys_call_table, %r1
|
||||
or,= %r2,%r2,%r2
|
||||
addil L%(sys_call_table64-sys_call_table), %r1
|
||||
or,ev %r2,%r2,%r2
|
||||
ldil L%sys_call_table64, %r1
|
||||
ldo R%sys_call_table(%r1), %r19
|
||||
or,= %r2,%r2,%r2
|
||||
or,ev %r2,%r2,%r2
|
||||
ldo R%sys_call_table64(%r1), %r19
|
||||
#else
|
||||
load32 sys_call_table, %r19
|
||||
@@ -1310,6 +1310,8 @@ ENTRY(sys_call_table)
|
||||
END(sys_call_table)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#undef __SYSCALL_WITH_COMPAT
|
||||
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
|
||||
.align 8
|
||||
ENTRY(sys_call_table64)
|
||||
#include <asm/syscall_table_64.h> /* 64-bit syscalls */
|
||||
|
||||
@@ -111,6 +111,21 @@ extern struct vdso_arch_data *vdso_data;
|
||||
addi \ptr, \ptr, (_vdso_datapage - 999b)@l
|
||||
.endm
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
.macro get_realdatapage ptr scratch
|
||||
get_datapage \ptr
|
||||
#ifdef CONFIG_TIME_NS
|
||||
lwz \scratch, VDSO_CLOCKMODE_OFFSET(\ptr)
|
||||
xoris \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@h
|
||||
xori \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@l
|
||||
cntlzw \scratch, \scratch
|
||||
rlwinm \scratch, \scratch, PAGE_SHIFT - 5, 1 << PAGE_SHIFT
|
||||
add \ptr, \ptr, \scratch
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
@@ -347,6 +347,8 @@ int main(void)
|
||||
#else
|
||||
OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, syscall_map);
|
||||
#endif
|
||||
OFFSET(VDSO_CLOCKMODE_OFFSET, vdso_arch_data, data[0].clock_mode);
|
||||
DEFINE(VDSO_CLOCKMODE_TIMENS, VDSO_CLOCKMODE_TIMENS);
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
|
||||
|
||||
@@ -30,7 +30,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
|
||||
#ifdef CONFIG_PPC64
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
get_datapage r10
|
||||
get_realdatapage r10, r11
|
||||
mtlr r12
|
||||
.cfi_restore lr
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
mr. r4,r3
|
||||
get_datapage r3
|
||||
get_realdatapage r3, r11
|
||||
mtlr r12
|
||||
#ifdef __powerpc64__
|
||||
addi r3,r3,CFG_SYSCALL_MAP64
|
||||
@@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
|
||||
.cfi_startproc
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
get_datapage r3
|
||||
get_realdatapage r3, r11
|
||||
#ifndef __powerpc64__
|
||||
lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
|
||||
#endif
|
||||
|
||||
@@ -343,23 +343,6 @@ int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* pseries error logs are in BE format, convert to cpu type */
|
||||
switch (hp_elog->id_type) {
|
||||
case PSERIES_HP_ELOG_ID_DRC_COUNT:
|
||||
hp_elog->_drc_u.drc_count =
|
||||
be32_to_cpu(hp_elog->_drc_u.drc_count);
|
||||
break;
|
||||
case PSERIES_HP_ELOG_ID_DRC_INDEX:
|
||||
hp_elog->_drc_u.drc_index =
|
||||
be32_to_cpu(hp_elog->_drc_u.drc_index);
|
||||
break;
|
||||
case PSERIES_HP_ELOG_ID_DRC_IC:
|
||||
hp_elog->_drc_u.ic.count =
|
||||
be32_to_cpu(hp_elog->_drc_u.ic.count);
|
||||
hp_elog->_drc_u.ic.index =
|
||||
be32_to_cpu(hp_elog->_drc_u.ic.index);
|
||||
}
|
||||
|
||||
switch (hp_elog->resource) {
|
||||
case PSERIES_HP_ELOG_RESOURCE_MEM:
|
||||
rc = dlpar_memory(hp_elog);
|
||||
|
||||
@@ -748,7 +748,7 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
|
||||
u32 drc_index;
|
||||
int rc;
|
||||
|
||||
drc_index = hp_elog->_drc_u.drc_index;
|
||||
drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
|
||||
|
||||
lock_device_hotplug();
|
||||
|
||||
|
||||
@@ -876,16 +876,16 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
|
||||
case PSERIES_HP_ELOG_ACTION_ADD:
|
||||
switch (hp_elog->id_type) {
|
||||
case PSERIES_HP_ELOG_ID_DRC_COUNT:
|
||||
count = hp_elog->_drc_u.drc_count;
|
||||
count = be32_to_cpu(hp_elog->_drc_u.drc_count);
|
||||
rc = dlpar_memory_add_by_count(count);
|
||||
break;
|
||||
case PSERIES_HP_ELOG_ID_DRC_INDEX:
|
||||
drc_index = hp_elog->_drc_u.drc_index;
|
||||
drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
|
||||
rc = dlpar_memory_add_by_index(drc_index);
|
||||
break;
|
||||
case PSERIES_HP_ELOG_ID_DRC_IC:
|
||||
count = hp_elog->_drc_u.ic.count;
|
||||
drc_index = hp_elog->_drc_u.ic.index;
|
||||
count = be32_to_cpu(hp_elog->_drc_u.ic.count);
|
||||
drc_index = be32_to_cpu(hp_elog->_drc_u.ic.index);
|
||||
rc = dlpar_memory_add_by_ic(count, drc_index);
|
||||
break;
|
||||
default:
|
||||
@@ -897,16 +897,16 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
|
||||
case PSERIES_HP_ELOG_ACTION_REMOVE:
|
||||
switch (hp_elog->id_type) {
|
||||
case PSERIES_HP_ELOG_ID_DRC_COUNT:
|
||||
count = hp_elog->_drc_u.drc_count;
|
||||
count = be32_to_cpu(hp_elog->_drc_u.drc_count);
|
||||
rc = dlpar_memory_remove_by_count(count);
|
||||
break;
|
||||
case PSERIES_HP_ELOG_ID_DRC_INDEX:
|
||||
drc_index = hp_elog->_drc_u.drc_index;
|
||||
drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
|
||||
rc = dlpar_memory_remove_by_index(drc_index);
|
||||
break;
|
||||
case PSERIES_HP_ELOG_ID_DRC_IC:
|
||||
count = hp_elog->_drc_u.ic.count;
|
||||
drc_index = hp_elog->_drc_u.ic.index;
|
||||
count = be32_to_cpu(hp_elog->_drc_u.ic.count);
|
||||
drc_index = be32_to_cpu(hp_elog->_drc_u.ic.index);
|
||||
rc = dlpar_memory_remove_by_ic(count, drc_index);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -121,7 +121,7 @@ int dlpar_hp_pmem(struct pseries_hp_errorlog *hp_elog)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
drc_index = hp_elog->_drc_u.drc_index;
|
||||
drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
|
||||
|
||||
lock_device_hotplug();
|
||||
|
||||
|
||||
@@ -217,6 +217,11 @@ config GENERIC_HWEIGHT
|
||||
config FIX_EARLYCON_MEM
|
||||
def_bool MMU
|
||||
|
||||
config ILLEGAL_POINTER_VALUE
|
||||
hex
|
||||
default 0 if 32BIT
|
||||
default 0xdead000000000000 if 64BIT
|
||||
|
||||
config PGTABLE_LEVELS
|
||||
int
|
||||
default 5 if 64BIT
|
||||
|
||||
@@ -60,8 +60,10 @@ static inline int test_facility(unsigned long nr)
|
||||
unsigned long facilities_als[] = { FACILITIES_ALS };
|
||||
|
||||
if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
|
||||
if (__test_facility(nr, &facilities_als))
|
||||
return 1;
|
||||
if (__test_facility(nr, &facilities_als)) {
|
||||
if (!__is_defined(__DECOMPRESSOR))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return __test_facility(nr, &stfle_fac_list);
|
||||
}
|
||||
|
||||
@@ -1432,7 +1432,7 @@ static int aux_output_begin(struct perf_output_handle *handle,
|
||||
unsigned long head, base, offset;
|
||||
struct hws_trailer_entry *te;
|
||||
|
||||
if (WARN_ON_ONCE(handle->head & ~PAGE_MASK))
|
||||
if (handle->head & ~PAGE_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
aux->head = handle->head >> PAGE_SHIFT;
|
||||
@@ -1613,7 +1613,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
|
||||
unsigned long num_sdb;
|
||||
|
||||
aux = perf_get_aux(handle);
|
||||
if (WARN_ON_ONCE(!aux))
|
||||
if (!aux)
|
||||
return;
|
||||
|
||||
/* Inform user space new data arrived */
|
||||
@@ -1635,7 +1635,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
if (WARN_ON_ONCE(!aux))
|
||||
if (!aux)
|
||||
return;
|
||||
|
||||
/* Update head and alert_mark to new position */
|
||||
@@ -1870,12 +1870,8 @@ static void cpumsf_pmu_start(struct perf_event *event, int flags)
|
||||
{
|
||||
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
|
||||
|
||||
if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
|
||||
if (!(event->hw.state & PERF_HES_STOPPED))
|
||||
return;
|
||||
|
||||
if (flags & PERF_EF_RELOAD)
|
||||
WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
|
||||
|
||||
perf_pmu_disable(event->pmu);
|
||||
event->hw.state = 0;
|
||||
cpuhw->lsctl.cs = 1;
|
||||
|
||||
@@ -95,11 +95,12 @@ static long cmm_alloc_pages(long nr, long *counter,
|
||||
(*counter)++;
|
||||
spin_unlock(&cmm_lock);
|
||||
nr--;
|
||||
cond_resched();
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
|
||||
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
|
||||
static long __cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
|
||||
{
|
||||
struct cmm_page_array *pa;
|
||||
unsigned long addr;
|
||||
@@ -123,6 +124,21 @@ static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
|
||||
return nr;
|
||||
}
|
||||
|
||||
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
|
||||
{
|
||||
long inc = 0;
|
||||
|
||||
while (nr) {
|
||||
inc = min(256L, nr);
|
||||
nr -= inc;
|
||||
inc = __cmm_free_pages(inc, counter, list);
|
||||
if (inc)
|
||||
break;
|
||||
cond_resched();
|
||||
}
|
||||
return nr + inc;
|
||||
}
|
||||
|
||||
static int cmm_oom_notify(struct notifier_block *self,
|
||||
unsigned long dummy, void *parm)
|
||||
{
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include <asm/desc.h>
|
||||
#include <asm/ldt.h>
|
||||
#include <asm/unwind.h>
|
||||
#include <asm/uprobes.h>
|
||||
#include <asm/ibt.h>
|
||||
|
||||
#include "perf_event.h"
|
||||
|
||||
@@ -2841,6 +2843,46 @@ static unsigned long get_segment_base(unsigned int segment)
|
||||
return get_desc_base(desc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UPROBES
|
||||
/*
|
||||
* Heuristic-based check if uprobe is installed at the function entry.
|
||||
*
|
||||
* Under assumption of user code being compiled with frame pointers,
|
||||
* `push %rbp/%ebp` is a good indicator that we indeed are.
|
||||
*
|
||||
* Similarly, `endbr64` (assuming 64-bit mode) is also a common pattern.
|
||||
* If we get this wrong, captured stack trace might have one extra bogus
|
||||
* entry, but the rest of stack trace will still be meaningful.
|
||||
*/
|
||||
static bool is_uprobe_at_func_entry(struct pt_regs *regs)
|
||||
{
|
||||
struct arch_uprobe *auprobe;
|
||||
|
||||
if (!current->utask)
|
||||
return false;
|
||||
|
||||
auprobe = current->utask->auprobe;
|
||||
if (!auprobe)
|
||||
return false;
|
||||
|
||||
/* push %rbp/%ebp */
|
||||
if (auprobe->insn[0] == 0x55)
|
||||
return true;
|
||||
|
||||
/* endbr64 (64-bit only) */
|
||||
if (user_64bit_mode(regs) && is_endbr(*(u32 *)auprobe->insn))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
static bool is_uprobe_at_func_entry(struct pt_regs *regs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_UPROBES */
|
||||
|
||||
#ifdef CONFIG_IA32_EMULATION
|
||||
|
||||
#include <linux/compat.h>
|
||||
@@ -2852,6 +2894,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
|
||||
unsigned long ss_base, cs_base;
|
||||
struct stack_frame_ia32 frame;
|
||||
const struct stack_frame_ia32 __user *fp;
|
||||
u32 ret_addr;
|
||||
|
||||
if (user_64bit_mode(regs))
|
||||
return 0;
|
||||
@@ -2861,6 +2904,12 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
|
||||
|
||||
fp = compat_ptr(ss_base + regs->bp);
|
||||
pagefault_disable();
|
||||
|
||||
/* see perf_callchain_user() below for why we do this */
|
||||
if (is_uprobe_at_func_entry(regs) &&
|
||||
!get_user(ret_addr, (const u32 __user *)regs->sp))
|
||||
perf_callchain_store(entry, ret_addr);
|
||||
|
||||
while (entry->nr < entry->max_stack) {
|
||||
if (!valid_user_frame(fp, sizeof(frame)))
|
||||
break;
|
||||
@@ -2889,6 +2938,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
|
||||
{
|
||||
struct stack_frame frame;
|
||||
const struct stack_frame __user *fp;
|
||||
unsigned long ret_addr;
|
||||
|
||||
if (perf_guest_state()) {
|
||||
/* TODO: We don't support guest os callchain now */
|
||||
@@ -2912,6 +2962,19 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
|
||||
return;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
/*
|
||||
* If we are called from uprobe handler, and we are indeed at the very
|
||||
* entry to user function (which is normally a `push %rbp` instruction,
|
||||
* under assumption of application being compiled with frame pointers),
|
||||
* we should read return address from *regs->sp before proceeding
|
||||
* to follow frame pointers, otherwise we'll skip immediate caller
|
||||
* as %rbp is not yet setup.
|
||||
*/
|
||||
if (is_uprobe_at_func_entry(regs) &&
|
||||
!get_user(ret_addr, (const unsigned long __user *)regs->sp))
|
||||
perf_callchain_store(entry, ret_addr);
|
||||
|
||||
while (entry->nr < entry->max_stack) {
|
||||
if (!valid_user_frame(fp, sizeof(frame)))
|
||||
break;
|
||||
|
||||
@@ -82,7 +82,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
|
||||
struct pt_regs *regs,
|
||||
unsigned long *args)
|
||||
{
|
||||
memcpy(args, ®s->bx, 6 * sizeof(args[0]));
|
||||
args[0] = regs->bx;
|
||||
args[1] = regs->cx;
|
||||
args[2] = regs->dx;
|
||||
args[3] = regs->si;
|
||||
args[4] = regs->di;
|
||||
args[5] = regs->bp;
|
||||
}
|
||||
|
||||
static inline int syscall_get_arch(struct task_struct *task)
|
||||
|
||||
@@ -351,27 +351,26 @@ static void ioapic_mask_entry(int apic, int pin)
|
||||
* shared ISA-space IRQs, so we have to support them. We are super
|
||||
* fast in the common case, and fast for shared ISA-space IRQs.
|
||||
*/
|
||||
static int __add_pin_to_irq_node(struct mp_chip_data *data,
|
||||
int node, int apic, int pin)
|
||||
static bool add_pin_to_irq_node(struct mp_chip_data *data, int node, int apic, int pin)
|
||||
{
|
||||
struct irq_pin_list *entry;
|
||||
|
||||
/* don't allow duplicates */
|
||||
for_each_irq_pin(entry, data->irq_2_pin)
|
||||
/* Don't allow duplicates */
|
||||
for_each_irq_pin(entry, data->irq_2_pin) {
|
||||
if (entry->apic == apic && entry->pin == pin)
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
entry = kzalloc_node(sizeof(struct irq_pin_list), GFP_ATOMIC, node);
|
||||
if (!entry) {
|
||||
pr_err("can not alloc irq_pin_list (%d,%d,%d)\n",
|
||||
node, apic, pin);
|
||||
return -ENOMEM;
|
||||
pr_err("Cannot allocate irq_pin_list (%d,%d,%d)\n", node, apic, pin);
|
||||
return false;
|
||||
}
|
||||
|
||||
entry->apic = apic;
|
||||
entry->pin = pin;
|
||||
list_add_tail(&entry->list, &data->irq_2_pin);
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin)
|
||||
@@ -386,13 +385,6 @@ static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin)
|
||||
}
|
||||
}
|
||||
|
||||
static void add_pin_to_irq_node(struct mp_chip_data *data,
|
||||
int node, int apic, int pin)
|
||||
{
|
||||
if (__add_pin_to_irq_node(data, node, apic, pin))
|
||||
panic("IO-APIC: failed to add irq-pin. Can not proceed\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Reroute an IRQ to a different pin.
|
||||
*/
|
||||
@@ -1001,8 +993,7 @@ static int alloc_isa_irq_from_domain(struct irq_domain *domain,
|
||||
if (irq_data && irq_data->parent_data) {
|
||||
if (!mp_check_pin_attr(irq, info))
|
||||
return -EBUSY;
|
||||
if (__add_pin_to_irq_node(irq_data->chip_data, node, ioapic,
|
||||
info->ioapic.pin))
|
||||
if (!add_pin_to_irq_node(irq_data->chip_data, node, ioapic, info->ioapic.pin))
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
info->flags |= X86_IRQ_ALLOC_LEGACY;
|
||||
@@ -3038,10 +3029,8 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
return -ENOMEM;
|
||||
|
||||
ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, info);
|
||||
if (ret < 0) {
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto free_data;
|
||||
|
||||
INIT_LIST_HEAD(&data->irq_2_pin);
|
||||
irq_data->hwirq = info->ioapic.pin;
|
||||
@@ -3050,7 +3039,10 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
irq_data->chip_data = data;
|
||||
mp_irqdomain_get_attr(mp_pin_to_gsi(ioapic, pin), data, info);
|
||||
|
||||
add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin);
|
||||
if (!add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin)) {
|
||||
ret = -ENOMEM;
|
||||
goto free_irqs;
|
||||
}
|
||||
|
||||
mp_preconfigure_entry(data);
|
||||
mp_register_handler(virq, data->is_level);
|
||||
@@ -3065,6 +3057,12 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
ioapic, mpc_ioapic_id(ioapic), pin, virq,
|
||||
data->is_level, data->active_low);
|
||||
return 0;
|
||||
|
||||
free_irqs:
|
||||
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
|
||||
free_data:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <asm/setup.h>
|
||||
#include <asm/set_memory.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/efi.h>
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/*
|
||||
@@ -90,6 +91,8 @@ map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p)
|
||||
{
|
||||
#ifdef CONFIG_EFI
|
||||
unsigned long mstart, mend;
|
||||
void *kaddr;
|
||||
int ret;
|
||||
|
||||
if (!efi_enabled(EFI_BOOT))
|
||||
return 0;
|
||||
@@ -105,6 +108,30 @@ map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p)
|
||||
if (!mstart)
|
||||
return 0;
|
||||
|
||||
ret = kernel_ident_mapping_init(info, level4p, mstart, mend);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
kaddr = memremap(mstart, mend - mstart, MEMREMAP_WB);
|
||||
if (!kaddr) {
|
||||
pr_err("Could not map UEFI system table\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mstart = efi_config_table;
|
||||
|
||||
if (efi_enabled(EFI_64BIT)) {
|
||||
efi_system_table_64_t *stbl = (efi_system_table_64_t *)kaddr;
|
||||
|
||||
mend = mstart + sizeof(efi_config_table_64_t) * stbl->nr_tables;
|
||||
} else {
|
||||
efi_system_table_32_t *stbl = (efi_system_table_32_t *)kaddr;
|
||||
|
||||
mend = mstart + sizeof(efi_config_table_32_t) * stbl->nr_tables;
|
||||
}
|
||||
|
||||
memunmap(kaddr);
|
||||
|
||||
return kernel_ident_mapping_init(info, level4p, mstart, mend);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
@@ -57,6 +57,56 @@ static bool is_imm8(int value)
|
||||
return value <= 127 && value >= -128;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let us limit the positive offset to be <= 123.
|
||||
* This is to ensure eventual jit convergence For the following patterns:
|
||||
* ...
|
||||
* pass4, final_proglen=4391:
|
||||
* ...
|
||||
* 20e: 48 85 ff test rdi,rdi
|
||||
* 211: 74 7d je 0x290
|
||||
* 213: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
|
||||
* ...
|
||||
* 289: 48 85 ff test rdi,rdi
|
||||
* 28c: 74 17 je 0x2a5
|
||||
* 28e: e9 7f ff ff ff jmp 0x212
|
||||
* 293: bf 03 00 00 00 mov edi,0x3
|
||||
* Note that insn at 0x211 is 2-byte cond jump insn for offset 0x7d (-125)
|
||||
* and insn at 0x28e is 5-byte jmp insn with offset -129.
|
||||
*
|
||||
* pass5, final_proglen=4392:
|
||||
* ...
|
||||
* 20e: 48 85 ff test rdi,rdi
|
||||
* 211: 0f 84 80 00 00 00 je 0x297
|
||||
* 217: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
|
||||
* ...
|
||||
* 28d: 48 85 ff test rdi,rdi
|
||||
* 290: 74 1a je 0x2ac
|
||||
* 292: eb 84 jmp 0x218
|
||||
* 294: bf 03 00 00 00 mov edi,0x3
|
||||
* Note that insn at 0x211 is 6-byte cond jump insn now since its offset
|
||||
* becomes 0x80 based on previous round (0x293 - 0x213 = 0x80).
|
||||
* At the same time, insn at 0x292 is a 2-byte insn since its offset is
|
||||
* -124.
|
||||
*
|
||||
* pass6 will repeat the same code as in pass4 and this will prevent
|
||||
* eventual convergence.
|
||||
*
|
||||
* To fix this issue, we need to break je (2->6 bytes) <-> jmp (5->2 bytes)
|
||||
* cycle in the above. In the above example je offset <= 0x7c should work.
|
||||
*
|
||||
* For other cases, je <-> je needs offset <= 0x7b to avoid no convergence
|
||||
* issue. For jmp <-> je and jmp <-> jmp cases, jmp offset <= 0x7c should
|
||||
* avoid no convergence issue.
|
||||
*
|
||||
* Overall, let us limit the positive offset for 8bit cond/uncond jmp insn
|
||||
* to maximum 123 (0x7b). This way, the jit pass can eventually converge.
|
||||
*/
|
||||
static bool is_imm8_jmp_offset(int value)
|
||||
{
|
||||
return value <= 123 && value >= -128;
|
||||
}
|
||||
|
||||
static bool is_simm32(s64 value)
|
||||
{
|
||||
return value == (s64)(s32)value;
|
||||
@@ -1589,7 +1639,7 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */
|
||||
return -EFAULT;
|
||||
}
|
||||
jmp_offset = addrs[i + insn->off] - addrs[i];
|
||||
if (is_imm8(jmp_offset)) {
|
||||
if (is_imm8_jmp_offset(jmp_offset)) {
|
||||
if (jmp_padding) {
|
||||
/* To keep the jmp_offset valid, the extra bytes are
|
||||
* padded before the jump insn, so we subtract the
|
||||
@@ -1663,7 +1713,7 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */
|
||||
break;
|
||||
}
|
||||
emit_jmp:
|
||||
if (is_imm8(jmp_offset)) {
|
||||
if (is_imm8_jmp_offset(jmp_offset)) {
|
||||
if (jmp_padding) {
|
||||
/* To avoid breaking jmp_offset, the extra bytes
|
||||
* are padded before the actual jmp insn, so
|
||||
|
||||
@@ -212,61 +212,44 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
|
||||
return true;
|
||||
}
|
||||
|
||||
struct integrity_sysfs_entry {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct blk_integrity *, char *);
|
||||
ssize_t (*store)(struct blk_integrity *, const char *, size_t);
|
||||
};
|
||||
|
||||
static ssize_t integrity_attr_show(struct kobject *kobj, struct attribute *attr,
|
||||
char *page)
|
||||
static inline struct blk_integrity *dev_to_bi(struct device *dev)
|
||||
{
|
||||
struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj);
|
||||
struct blk_integrity *bi = &disk->queue->integrity;
|
||||
struct integrity_sysfs_entry *entry =
|
||||
container_of(attr, struct integrity_sysfs_entry, attr);
|
||||
|
||||
return entry->show(bi, page);
|
||||
return &dev_to_disk(dev)->queue->integrity;
|
||||
}
|
||||
|
||||
static ssize_t integrity_attr_store(struct kobject *kobj,
|
||||
struct attribute *attr, const char *page,
|
||||
size_t count)
|
||||
static ssize_t format_show(struct device *dev, struct device_attribute *attr,
|
||||
char *page)
|
||||
{
|
||||
struct gendisk *disk = container_of(kobj, struct gendisk, integrity_kobj);
|
||||
struct blk_integrity *bi = &disk->queue->integrity;
|
||||
struct integrity_sysfs_entry *entry =
|
||||
container_of(attr, struct integrity_sysfs_entry, attr);
|
||||
ssize_t ret = 0;
|
||||
struct blk_integrity *bi = dev_to_bi(dev);
|
||||
|
||||
if (entry->store)
|
||||
ret = entry->store(bi, page, count);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t integrity_format_show(struct blk_integrity *bi, char *page)
|
||||
{
|
||||
if (bi->profile && bi->profile->name)
|
||||
return sprintf(page, "%s\n", bi->profile->name);
|
||||
else
|
||||
return sprintf(page, "none\n");
|
||||
return sysfs_emit(page, "%s\n", bi->profile->name);
|
||||
return sysfs_emit(page, "none\n");
|
||||
}
|
||||
|
||||
static ssize_t integrity_tag_size_show(struct blk_integrity *bi, char *page)
|
||||
static ssize_t tag_size_show(struct device *dev, struct device_attribute *attr,
|
||||
char *page)
|
||||
{
|
||||
return sprintf(page, "%u\n", bi->tag_size);
|
||||
struct blk_integrity *bi = dev_to_bi(dev);
|
||||
|
||||
return sysfs_emit(page, "%u\n", bi->tag_size);
|
||||
}
|
||||
|
||||
static ssize_t integrity_interval_show(struct blk_integrity *bi, char *page)
|
||||
static ssize_t protection_interval_bytes_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *page)
|
||||
{
|
||||
return sprintf(page, "%u\n",
|
||||
bi->interval_exp ? 1 << bi->interval_exp : 0);
|
||||
struct blk_integrity *bi = dev_to_bi(dev);
|
||||
|
||||
return sysfs_emit(page, "%u\n",
|
||||
bi->interval_exp ? 1 << bi->interval_exp : 0);
|
||||
}
|
||||
|
||||
static ssize_t integrity_verify_store(struct blk_integrity *bi,
|
||||
const char *page, size_t count)
|
||||
static ssize_t read_verify_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct blk_integrity *bi = dev_to_bi(dev);
|
||||
char *p = (char *) page;
|
||||
unsigned long val = simple_strtoul(p, &p, 10);
|
||||
|
||||
@@ -278,14 +261,20 @@ static ssize_t integrity_verify_store(struct blk_integrity *bi,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t integrity_verify_show(struct blk_integrity *bi, char *page)
|
||||
static ssize_t read_verify_show(struct device *dev,
|
||||
struct device_attribute *attr, char *page)
|
||||
{
|
||||
return sprintf(page, "%d\n", (bi->flags & BLK_INTEGRITY_VERIFY) != 0);
|
||||
struct blk_integrity *bi = dev_to_bi(dev);
|
||||
|
||||
return sysfs_emit(page, "%d\n", !!(bi->flags & BLK_INTEGRITY_VERIFY));
|
||||
}
|
||||
|
||||
static ssize_t integrity_generate_store(struct blk_integrity *bi,
|
||||
const char *page, size_t count)
|
||||
static ssize_t write_generate_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct blk_integrity *bi = dev_to_bi(dev);
|
||||
|
||||
char *p = (char *) page;
|
||||
unsigned long val = simple_strtoul(p, &p, 10);
|
||||
|
||||
@@ -297,68 +286,44 @@ static ssize_t integrity_generate_store(struct blk_integrity *bi,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t integrity_generate_show(struct blk_integrity *bi, char *page)
|
||||
static ssize_t write_generate_show(struct device *dev,
|
||||
struct device_attribute *attr, char *page)
|
||||
{
|
||||
return sprintf(page, "%d\n", (bi->flags & BLK_INTEGRITY_GENERATE) != 0);
|
||||
struct blk_integrity *bi = dev_to_bi(dev);
|
||||
|
||||
return sysfs_emit(page, "%d\n", !!(bi->flags & BLK_INTEGRITY_GENERATE));
|
||||
}
|
||||
|
||||
static ssize_t integrity_device_show(struct blk_integrity *bi, char *page)
|
||||
static ssize_t device_is_integrity_capable_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *page)
|
||||
{
|
||||
return sprintf(page, "%u\n",
|
||||
(bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE) != 0);
|
||||
struct blk_integrity *bi = dev_to_bi(dev);
|
||||
|
||||
return sysfs_emit(page, "%u\n",
|
||||
!!(bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE));
|
||||
}
|
||||
|
||||
static struct integrity_sysfs_entry integrity_format_entry = {
|
||||
.attr = { .name = "format", .mode = 0444 },
|
||||
.show = integrity_format_show,
|
||||
};
|
||||
|
||||
static struct integrity_sysfs_entry integrity_tag_size_entry = {
|
||||
.attr = { .name = "tag_size", .mode = 0444 },
|
||||
.show = integrity_tag_size_show,
|
||||
};
|
||||
|
||||
static struct integrity_sysfs_entry integrity_interval_entry = {
|
||||
.attr = { .name = "protection_interval_bytes", .mode = 0444 },
|
||||
.show = integrity_interval_show,
|
||||
};
|
||||
|
||||
static struct integrity_sysfs_entry integrity_verify_entry = {
|
||||
.attr = { .name = "read_verify", .mode = 0644 },
|
||||
.show = integrity_verify_show,
|
||||
.store = integrity_verify_store,
|
||||
};
|
||||
|
||||
static struct integrity_sysfs_entry integrity_generate_entry = {
|
||||
.attr = { .name = "write_generate", .mode = 0644 },
|
||||
.show = integrity_generate_show,
|
||||
.store = integrity_generate_store,
|
||||
};
|
||||
|
||||
static struct integrity_sysfs_entry integrity_device_entry = {
|
||||
.attr = { .name = "device_is_integrity_capable", .mode = 0444 },
|
||||
.show = integrity_device_show,
|
||||
};
|
||||
static DEVICE_ATTR_RO(format);
|
||||
static DEVICE_ATTR_RO(tag_size);
|
||||
static DEVICE_ATTR_RO(protection_interval_bytes);
|
||||
static DEVICE_ATTR_RW(read_verify);
|
||||
static DEVICE_ATTR_RW(write_generate);
|
||||
static DEVICE_ATTR_RO(device_is_integrity_capable);
|
||||
|
||||
static struct attribute *integrity_attrs[] = {
|
||||
&integrity_format_entry.attr,
|
||||
&integrity_tag_size_entry.attr,
|
||||
&integrity_interval_entry.attr,
|
||||
&integrity_verify_entry.attr,
|
||||
&integrity_generate_entry.attr,
|
||||
&integrity_device_entry.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(integrity);
|
||||
|
||||
static const struct sysfs_ops integrity_ops = {
|
||||
.show = &integrity_attr_show,
|
||||
.store = &integrity_attr_store,
|
||||
&dev_attr_format.attr,
|
||||
&dev_attr_tag_size.attr,
|
||||
&dev_attr_protection_interval_bytes.attr,
|
||||
&dev_attr_read_verify.attr,
|
||||
&dev_attr_write_generate.attr,
|
||||
&dev_attr_device_is_integrity_capable.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct kobj_type integrity_ktype = {
|
||||
.default_groups = integrity_groups,
|
||||
.sysfs_ops = &integrity_ops,
|
||||
const struct attribute_group blk_integrity_attr_group = {
|
||||
.name = "integrity",
|
||||
.attrs = integrity_attrs,
|
||||
};
|
||||
|
||||
static blk_status_t blk_integrity_nop_fn(struct blk_integrity_iter *iter)
|
||||
@@ -435,21 +400,3 @@ void blk_integrity_unregister(struct gendisk *disk)
|
||||
memset(bi, 0, sizeof(*bi));
|
||||
}
|
||||
EXPORT_SYMBOL(blk_integrity_unregister);
|
||||
|
||||
int blk_integrity_add(struct gendisk *disk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = kobject_init_and_add(&disk->integrity_kobj, &integrity_ktype,
|
||||
&disk_to_dev(disk)->kobj, "%s", "integrity");
|
||||
if (!ret)
|
||||
kobject_uevent(&disk->integrity_kobj, KOBJ_ADD);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void blk_integrity_del(struct gendisk *disk)
|
||||
{
|
||||
kobject_uevent(&disk->integrity_kobj, KOBJ_REMOVE);
|
||||
kobject_del(&disk->integrity_kobj);
|
||||
kobject_put(&disk->integrity_kobj);
|
||||
}
|
||||
|
||||
@@ -2057,7 +2057,7 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors,
|
||||
struct ioc_now *now)
|
||||
{
|
||||
struct ioc_gq *iocg;
|
||||
u64 dur, usage_pct, nr_cycles;
|
||||
u64 dur, usage_pct, nr_cycles, nr_cycles_shift;
|
||||
|
||||
/* if no debtor, reset the cycle */
|
||||
if (!nr_debtors) {
|
||||
@@ -2119,10 +2119,12 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors,
|
||||
old_debt = iocg->abs_vdebt;
|
||||
old_delay = iocg->delay;
|
||||
|
||||
nr_cycles_shift = min_t(u64, nr_cycles, BITS_PER_LONG - 1);
|
||||
if (iocg->abs_vdebt)
|
||||
iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles ?: 1;
|
||||
iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles_shift ?: 1;
|
||||
|
||||
if (iocg->delay)
|
||||
iocg->delay = iocg->delay >> nr_cycles ?: 1;
|
||||
iocg->delay = iocg->delay >> nr_cycles_shift ?: 1;
|
||||
|
||||
iocg_kick_waitq(iocg, true, now);
|
||||
|
||||
|
||||
10
block/blk.h
10
block/blk.h
@@ -240,8 +240,7 @@ static inline bool integrity_req_gap_front_merge(struct request *req,
|
||||
bip_next->bip_vec[0].bv_offset);
|
||||
}
|
||||
|
||||
int blk_integrity_add(struct gendisk *disk);
|
||||
void blk_integrity_del(struct gendisk *);
|
||||
extern const struct attribute_group blk_integrity_attr_group;
|
||||
#else /* CONFIG_BLK_DEV_INTEGRITY */
|
||||
static inline bool blk_integrity_merge_rq(struct request_queue *rq,
|
||||
struct request *r1, struct request *r2)
|
||||
@@ -274,13 +273,6 @@ static inline bool bio_integrity_endio(struct bio *bio)
|
||||
static inline void bio_integrity_free(struct bio *bio)
|
||||
{
|
||||
}
|
||||
static inline int blk_integrity_add(struct gendisk *disk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void blk_integrity_del(struct gendisk *disk)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_BLK_DEV_INTEGRITY */
|
||||
|
||||
unsigned long blk_rq_timeout(unsigned long timeout);
|
||||
|
||||
@@ -491,15 +491,11 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
|
||||
*/
|
||||
pm_runtime_set_memalloc_noio(ddev, true);
|
||||
|
||||
ret = blk_integrity_add(disk);
|
||||
if (ret)
|
||||
goto out_del_block_link;
|
||||
|
||||
disk->part0->bd_holder_dir =
|
||||
kobject_create_and_add("holders", &ddev->kobj);
|
||||
if (!disk->part0->bd_holder_dir) {
|
||||
ret = -ENOMEM;
|
||||
goto out_del_integrity;
|
||||
goto out_del_block_link;
|
||||
}
|
||||
disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
|
||||
if (!disk->slave_dir) {
|
||||
@@ -566,8 +562,6 @@ out_put_slave_dir:
|
||||
disk->slave_dir = NULL;
|
||||
out_put_holder_dir:
|
||||
kobject_put(disk->part0->bd_holder_dir);
|
||||
out_del_integrity:
|
||||
blk_integrity_del(disk);
|
||||
out_del_block_link:
|
||||
if (!sysfs_deprecated)
|
||||
sysfs_remove_link(block_depr, dev_name(ddev));
|
||||
@@ -626,7 +620,6 @@ void del_gendisk(struct gendisk *disk)
|
||||
if (WARN_ON_ONCE(!disk_live(disk) && !(disk->flags & GENHD_FL_HIDDEN)))
|
||||
return;
|
||||
|
||||
blk_integrity_del(disk);
|
||||
disk_del_events(disk);
|
||||
|
||||
mutex_lock(&disk->open_mutex);
|
||||
@@ -1162,6 +1155,9 @@ static const struct attribute_group *disk_attr_groups[] = {
|
||||
&disk_attr_group,
|
||||
#ifdef CONFIG_BLK_DEV_IO_TRACE
|
||||
&blk_trace_attr_group,
|
||||
#endif
|
||||
#ifdef CONFIG_BLK_DEV_INTEGRITY
|
||||
&blk_integrity_attr_group,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -136,27 +136,19 @@ static int simd_skcipher_init(struct crypto_skcipher *tfm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct simd_skcipher_alg *simd_skcipher_create_compat(const char *algname,
|
||||
struct simd_skcipher_alg *simd_skcipher_create_compat(struct skcipher_alg *ialg,
|
||||
const char *algname,
|
||||
const char *drvname,
|
||||
const char *basename)
|
||||
{
|
||||
struct simd_skcipher_alg *salg;
|
||||
struct crypto_skcipher *tfm;
|
||||
struct skcipher_alg *ialg;
|
||||
struct skcipher_alg *alg;
|
||||
int err;
|
||||
|
||||
tfm = crypto_alloc_skcipher(basename, CRYPTO_ALG_INTERNAL,
|
||||
CRYPTO_ALG_INTERNAL | CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(tfm))
|
||||
return ERR_CAST(tfm);
|
||||
|
||||
ialg = crypto_skcipher_alg(tfm);
|
||||
|
||||
salg = kzalloc(sizeof(*salg), GFP_KERNEL);
|
||||
if (!salg) {
|
||||
salg = ERR_PTR(-ENOMEM);
|
||||
goto out_put_tfm;
|
||||
goto out;
|
||||
}
|
||||
|
||||
salg->ialg_name = basename;
|
||||
@@ -195,30 +187,16 @@ struct simd_skcipher_alg *simd_skcipher_create_compat(const char *algname,
|
||||
if (err)
|
||||
goto out_free_salg;
|
||||
|
||||
out_put_tfm:
|
||||
crypto_free_skcipher(tfm);
|
||||
out:
|
||||
return salg;
|
||||
|
||||
out_free_salg:
|
||||
kfree(salg);
|
||||
salg = ERR_PTR(err);
|
||||
goto out_put_tfm;
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(simd_skcipher_create_compat);
|
||||
|
||||
struct simd_skcipher_alg *simd_skcipher_create(const char *algname,
|
||||
const char *basename)
|
||||
{
|
||||
char drvname[CRYPTO_MAX_ALG_NAME];
|
||||
|
||||
if (snprintf(drvname, CRYPTO_MAX_ALG_NAME, "simd-%s", basename) >=
|
||||
CRYPTO_MAX_ALG_NAME)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
||||
return simd_skcipher_create_compat(algname, drvname, basename);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(simd_skcipher_create);
|
||||
|
||||
void simd_skcipher_free(struct simd_skcipher_alg *salg)
|
||||
{
|
||||
crypto_unregister_skcipher(&salg->alg);
|
||||
@@ -246,7 +224,7 @@ int simd_register_skciphers_compat(struct skcipher_alg *algs, int count,
|
||||
algname = algs[i].base.cra_name + 2;
|
||||
drvname = algs[i].base.cra_driver_name + 2;
|
||||
basename = algs[i].base.cra_driver_name;
|
||||
simd = simd_skcipher_create_compat(algname, drvname, basename);
|
||||
simd = simd_skcipher_create_compat(algs + i, algname, drvname, basename);
|
||||
err = PTR_ERR(simd);
|
||||
if (IS_ERR(simd))
|
||||
goto err_unregister;
|
||||
@@ -383,27 +361,19 @@ static int simd_aead_init(struct crypto_aead *tfm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct simd_aead_alg *simd_aead_create_compat(const char *algname,
|
||||
const char *drvname,
|
||||
const char *basename)
|
||||
static struct simd_aead_alg *simd_aead_create_compat(struct aead_alg *ialg,
|
||||
const char *algname,
|
||||
const char *drvname,
|
||||
const char *basename)
|
||||
{
|
||||
struct simd_aead_alg *salg;
|
||||
struct crypto_aead *tfm;
|
||||
struct aead_alg *ialg;
|
||||
struct aead_alg *alg;
|
||||
int err;
|
||||
|
||||
tfm = crypto_alloc_aead(basename, CRYPTO_ALG_INTERNAL,
|
||||
CRYPTO_ALG_INTERNAL | CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(tfm))
|
||||
return ERR_CAST(tfm);
|
||||
|
||||
ialg = crypto_aead_alg(tfm);
|
||||
|
||||
salg = kzalloc(sizeof(*salg), GFP_KERNEL);
|
||||
if (!salg) {
|
||||
salg = ERR_PTR(-ENOMEM);
|
||||
goto out_put_tfm;
|
||||
goto out;
|
||||
}
|
||||
|
||||
salg->ialg_name = basename;
|
||||
@@ -442,36 +412,20 @@ struct simd_aead_alg *simd_aead_create_compat(const char *algname,
|
||||
if (err)
|
||||
goto out_free_salg;
|
||||
|
||||
out_put_tfm:
|
||||
crypto_free_aead(tfm);
|
||||
out:
|
||||
return salg;
|
||||
|
||||
out_free_salg:
|
||||
kfree(salg);
|
||||
salg = ERR_PTR(err);
|
||||
goto out_put_tfm;
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(simd_aead_create_compat);
|
||||
|
||||
struct simd_aead_alg *simd_aead_create(const char *algname,
|
||||
const char *basename)
|
||||
{
|
||||
char drvname[CRYPTO_MAX_ALG_NAME];
|
||||
|
||||
if (snprintf(drvname, CRYPTO_MAX_ALG_NAME, "simd-%s", basename) >=
|
||||
CRYPTO_MAX_ALG_NAME)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
||||
return simd_aead_create_compat(algname, drvname, basename);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(simd_aead_create);
|
||||
|
||||
void simd_aead_free(struct simd_aead_alg *salg)
|
||||
static void simd_aead_free(struct simd_aead_alg *salg)
|
||||
{
|
||||
crypto_unregister_aead(&salg->alg);
|
||||
kfree(salg);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(simd_aead_free);
|
||||
|
||||
int simd_register_aeads_compat(struct aead_alg *algs, int count,
|
||||
struct simd_aead_alg **simd_algs)
|
||||
@@ -493,7 +447,7 @@ int simd_register_aeads_compat(struct aead_alg *algs, int count,
|
||||
algname = algs[i].base.cra_name + 2;
|
||||
drvname = algs[i].base.cra_driver_name + 2;
|
||||
basename = algs[i].base.cra_driver_name;
|
||||
simd = simd_aead_create_compat(algname, drvname, basename);
|
||||
simd = simd_aead_create_compat(algs + i, algname, drvname, basename);
|
||||
err = PTR_ERR(simd);
|
||||
if (IS_ERR(simd))
|
||||
goto err_unregister;
|
||||
|
||||
@@ -130,8 +130,10 @@ static void exit_round_robin(unsigned int tsk_index)
|
||||
{
|
||||
struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
|
||||
|
||||
cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
|
||||
tsk_in_cpu[tsk_index] = -1;
|
||||
if (tsk_in_cpu[tsk_index] != -1) {
|
||||
cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
|
||||
tsk_in_cpu[tsk_index] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int idle_pct = 5; /* percentage */
|
||||
|
||||
@@ -174,6 +174,8 @@ acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object)
|
||||
elements =
|
||||
ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
|
||||
sizeof(union acpi_object));
|
||||
if (!elements)
|
||||
return (AE_NO_MEMORY);
|
||||
|
||||
this = string;
|
||||
for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {
|
||||
|
||||
@@ -437,6 +437,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
||||
|
||||
if (info->connection_node) {
|
||||
second_desc = info->connection_node->object;
|
||||
if (second_desc == NULL) {
|
||||
break;
|
||||
}
|
||||
if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
|
||||
status =
|
||||
acpi_ds_get_buffer_arguments(second_desc);
|
||||
|
||||
@@ -25,6 +25,8 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
|
||||
static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
|
||||
*parser_state);
|
||||
|
||||
static void acpi_ps_free_field_list(union acpi_parse_object *start);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ps_get_next_package_length
|
||||
@@ -683,6 +685,39 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
|
||||
return_PTR(field);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ps_free_field_list
|
||||
*
|
||||
* PARAMETERS: start - First Op in field list
|
||||
*
|
||||
* RETURN: None.
|
||||
*
|
||||
* DESCRIPTION: Free all Op objects inside a field list.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void acpi_ps_free_field_list(union acpi_parse_object *start)
|
||||
{
|
||||
union acpi_parse_object *cur = start;
|
||||
union acpi_parse_object *next;
|
||||
union acpi_parse_object *arg;
|
||||
|
||||
while (cur) {
|
||||
next = cur->common.next;
|
||||
|
||||
/* AML_INT_CONNECTION_OP can have a single argument */
|
||||
|
||||
arg = acpi_ps_get_arg(cur, 0);
|
||||
if (arg) {
|
||||
acpi_ps_free_op(arg);
|
||||
}
|
||||
|
||||
acpi_ps_free_op(cur);
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ps_get_next_arg
|
||||
@@ -751,6 +786,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
||||
while (parser_state->aml < parser_state->pkg_end) {
|
||||
field = acpi_ps_get_next_field(parser_state);
|
||||
if (!field) {
|
||||
if (arg) {
|
||||
acpi_ps_free_field_list(arg);
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
@@ -820,6 +859,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
||||
acpi_ps_get_next_namepath(walk_state, parser_state,
|
||||
arg,
|
||||
ACPI_NOT_METHOD_CALL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_ps_free_op(arg);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
} else {
|
||||
/* Single complex argument, nothing returned */
|
||||
|
||||
@@ -854,6 +897,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
||||
acpi_ps_get_next_namepath(walk_state, parser_state,
|
||||
arg,
|
||||
ACPI_POSSIBLE_METHOD_CALL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_ps_free_op(arg);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
|
||||
|
||||
|
||||
@@ -692,27 +692,34 @@ static LIST_HEAD(acpi_battery_list);
|
||||
static LIST_HEAD(battery_hook_list);
|
||||
static DEFINE_MUTEX(hook_mutex);
|
||||
|
||||
static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
|
||||
static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
|
||||
{
|
||||
struct acpi_battery *battery;
|
||||
|
||||
/*
|
||||
* In order to remove a hook, we first need to
|
||||
* de-register all the batteries that are registered.
|
||||
*/
|
||||
if (lock)
|
||||
mutex_lock(&hook_mutex);
|
||||
list_for_each_entry(battery, &acpi_battery_list, list) {
|
||||
hook->remove_battery(battery->bat);
|
||||
}
|
||||
list_del(&hook->list);
|
||||
if (lock)
|
||||
mutex_unlock(&hook_mutex);
|
||||
list_del_init(&hook->list);
|
||||
|
||||
pr_info("extension unregistered: %s\n", hook->name);
|
||||
}
|
||||
|
||||
void battery_hook_unregister(struct acpi_battery_hook *hook)
|
||||
{
|
||||
__battery_hook_unregister(hook, 1);
|
||||
mutex_lock(&hook_mutex);
|
||||
/*
|
||||
* Ignore already unregistered battery hooks. This might happen
|
||||
* if a battery hook was previously unloaded due to an error when
|
||||
* adding a new battery.
|
||||
*/
|
||||
if (!list_empty(&hook->list))
|
||||
battery_hook_unregister_unlocked(hook);
|
||||
|
||||
mutex_unlock(&hook_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(battery_hook_unregister);
|
||||
|
||||
@@ -721,7 +728,6 @@ void battery_hook_register(struct acpi_battery_hook *hook)
|
||||
struct acpi_battery *battery;
|
||||
|
||||
mutex_lock(&hook_mutex);
|
||||
INIT_LIST_HEAD(&hook->list);
|
||||
list_add(&hook->list, &battery_hook_list);
|
||||
/*
|
||||
* Now that the driver is registered, we need
|
||||
@@ -738,7 +744,7 @@ void battery_hook_register(struct acpi_battery_hook *hook)
|
||||
* hooks.
|
||||
*/
|
||||
pr_err("extension failed to load: %s", hook->name);
|
||||
__battery_hook_unregister(hook, 0);
|
||||
battery_hook_unregister_unlocked(hook);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@@ -775,7 +781,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
|
||||
*/
|
||||
pr_err("error in extension, unloading: %s",
|
||||
hook_node->name);
|
||||
__battery_hook_unregister(hook_node, 0);
|
||||
battery_hook_unregister_unlocked(hook_node);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&hook_mutex);
|
||||
@@ -808,7 +814,7 @@ static void __exit battery_hook_exit(void)
|
||||
* need to remove the hooks.
|
||||
*/
|
||||
list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
|
||||
__battery_hook_unregister(hook, 1);
|
||||
battery_hook_unregister(hook);
|
||||
}
|
||||
mutex_destroy(&hook_mutex);
|
||||
}
|
||||
|
||||
@@ -797,6 +797,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
|
||||
unsigned long tmp;
|
||||
int ret = 0;
|
||||
|
||||
if (t->rdata)
|
||||
memset(t->rdata, 0, t->rlen);
|
||||
|
||||
/* start transaction */
|
||||
spin_lock_irqsave(&ec->lock, tmp);
|
||||
/* Enable GPE for command processing (IBF=0/OBF=1) */
|
||||
@@ -833,8 +836,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
|
||||
|
||||
if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
|
||||
return -EINVAL;
|
||||
if (t->rdata)
|
||||
memset(t->rdata, 0, t->rlen);
|
||||
|
||||
mutex_lock(&ec->mutex);
|
||||
if (ec->global_lock) {
|
||||
@@ -861,7 +862,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec)
|
||||
.wdata = NULL, .rdata = &d,
|
||||
.wlen = 0, .rlen = 1};
|
||||
|
||||
return acpi_ec_transaction(ec, &t);
|
||||
return acpi_ec_transaction_unlocked(ec, &t);
|
||||
}
|
||||
|
||||
static int acpi_ec_burst_disable(struct acpi_ec *ec)
|
||||
@@ -871,7 +872,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec)
|
||||
.wlen = 0, .rlen = 0};
|
||||
|
||||
return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
|
||||
acpi_ec_transaction(ec, &t) : 0;
|
||||
acpi_ec_transaction_unlocked(ec, &t) : 0;
|
||||
}
|
||||
|
||||
static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
|
||||
@@ -887,6 +888,19 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_ec_read_unlocked(struct acpi_ec *ec, u8 address, u8 *data)
|
||||
{
|
||||
int result;
|
||||
u8 d;
|
||||
struct transaction t = {.command = ACPI_EC_COMMAND_READ,
|
||||
.wdata = &address, .rdata = &d,
|
||||
.wlen = 1, .rlen = 1};
|
||||
|
||||
result = acpi_ec_transaction_unlocked(ec, &t);
|
||||
*data = d;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
|
||||
{
|
||||
u8 wdata[2] = { address, data };
|
||||
@@ -897,6 +911,16 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
|
||||
return acpi_ec_transaction(ec, &t);
|
||||
}
|
||||
|
||||
static int acpi_ec_write_unlocked(struct acpi_ec *ec, u8 address, u8 data)
|
||||
{
|
||||
u8 wdata[2] = { address, data };
|
||||
struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
|
||||
.wdata = wdata, .rdata = NULL,
|
||||
.wlen = 2, .rlen = 0};
|
||||
|
||||
return acpi_ec_transaction_unlocked(ec, &t);
|
||||
}
|
||||
|
||||
int ec_read(u8 addr, u8 *val)
|
||||
{
|
||||
int err;
|
||||
@@ -1304,6 +1328,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
||||
struct acpi_ec *ec = handler_context;
|
||||
int result = 0, i, bytes = bits / 8;
|
||||
u8 *value = (u8 *)value64;
|
||||
u32 glk;
|
||||
|
||||
if ((address > 0xFF) || !value || !handler_context)
|
||||
return AE_BAD_PARAMETER;
|
||||
@@ -1311,13 +1336,25 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
||||
if (function != ACPI_READ && function != ACPI_WRITE)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
mutex_lock(&ec->mutex);
|
||||
|
||||
if (ec->global_lock) {
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
result = -ENODEV;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
if (ec->busy_polling || bits > 8)
|
||||
acpi_ec_burst_enable(ec);
|
||||
|
||||
for (i = 0; i < bytes; ++i, ++address, ++value) {
|
||||
result = (function == ACPI_READ) ?
|
||||
acpi_ec_read(ec, address, value) :
|
||||
acpi_ec_write(ec, address, *value);
|
||||
acpi_ec_read_unlocked(ec, address, value) :
|
||||
acpi_ec_write_unlocked(ec, address, *value);
|
||||
if (result < 0)
|
||||
break;
|
||||
}
|
||||
@@ -1325,6 +1362,12 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
||||
if (ec->busy_polling || bits > 8)
|
||||
acpi_ec_burst_disable(ec);
|
||||
|
||||
if (ec->global_lock)
|
||||
acpi_release_global_lock(glk);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&ec->mutex);
|
||||
|
||||
switch (result) {
|
||||
case -EINVAL:
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
@@ -439,6 +439,13 @@ static const struct dmi_system_id asus_laptop[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Asus Vivobook X1704VAP */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Asus ExpertBook B1402CBA",
|
||||
.matches = {
|
||||
@@ -506,6 +513,13 @@ static const struct dmi_system_id maingear_laptop[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-15A3070T"),
|
||||
}
|
||||
},
|
||||
{
|
||||
/* Asus ExpertBook B2502CVA */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */
|
||||
.matches = {
|
||||
|
||||
@@ -258,6 +258,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "PCG-FRV35"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Panasonic Toughbook CF-18 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Matsushita Electric Industrial"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Toshiba models with Transflective display, these need to use
|
||||
|
||||
@@ -46,10 +46,11 @@
|
||||
#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
|
||||
#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
|
||||
|
||||
/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
|
||||
* can overrun their FIFOs when used with the CSB5 */
|
||||
|
||||
static const char *csb_bad_ata100[] = {
|
||||
/*
|
||||
* Seagate Barracuda ATA IV Family drives in UDMA mode 5
|
||||
* can overrun their FIFOs when used with the CSB5.
|
||||
*/
|
||||
static const char * const csb_bad_ata100[] = {
|
||||
"ST320011A",
|
||||
"ST340016A",
|
||||
"ST360021A",
|
||||
@@ -163,10 +164,11 @@ static unsigned int serverworks_osb4_filter(struct ata_device *adev, unsigned in
|
||||
* @adev: ATA device
|
||||
* @mask: Mask of proposed modes
|
||||
*
|
||||
* Check the blacklist and disable UDMA5 if matched
|
||||
* Check the list of devices with broken UDMA5 and
|
||||
* disable UDMA5 if matched.
|
||||
*/
|
||||
|
||||
static unsigned int serverworks_csb_filter(struct ata_device *adev, unsigned int mask)
|
||||
static unsigned int serverworks_csb_filter(struct ata_device *adev,
|
||||
unsigned int mask)
|
||||
{
|
||||
const char *p;
|
||||
char model_num[ATA_ID_PROD_LEN + 1];
|
||||
|
||||
@@ -128,7 +128,7 @@ static const struct pci_device_id sil_pci_tbl[] = {
|
||||
static const struct sil_drivelist {
|
||||
const char *product;
|
||||
unsigned int quirk;
|
||||
} sil_blacklist [] = {
|
||||
} sil_quirks[] = {
|
||||
{ "ST320012AS", SIL_QUIRK_MOD15WRITE },
|
||||
{ "ST330013AS", SIL_QUIRK_MOD15WRITE },
|
||||
{ "ST340017AS", SIL_QUIRK_MOD15WRITE },
|
||||
@@ -600,8 +600,8 @@ static void sil_thaw(struct ata_port *ap)
|
||||
* list, and apply the fixups to only the specific
|
||||
* devices/hosts/firmwares that need it.
|
||||
*
|
||||
* 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted
|
||||
* The Maxtor quirk is in the blacklist, but I'm keeping the original
|
||||
* 20040111 - Seagate drives affected by the Mod15Write bug are quirked
|
||||
* The Maxtor quirk is in sil_quirks, but I'm keeping the original
|
||||
* pessimistic fix for the following reasons...
|
||||
* - There seems to be less info on it, only one device gleaned off the
|
||||
* Windows driver, maybe only one is affected. More info would be greatly
|
||||
@@ -620,9 +620,9 @@ static void sil_dev_config(struct ata_device *dev)
|
||||
|
||||
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
|
||||
|
||||
for (n = 0; sil_blacklist[n].product; n++)
|
||||
if (!strcmp(sil_blacklist[n].product, model_num)) {
|
||||
quirks = sil_blacklist[n].quirk;
|
||||
for (n = 0; sil_quirks[n].product; n++)
|
||||
if (!strcmp(sil_quirks[n].product, model_num)) {
|
||||
quirks = sil_quirks[n].quirk;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -361,6 +361,7 @@ ata_rw_frameinit(struct frame *f)
|
||||
}
|
||||
|
||||
ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
|
||||
dev_hold(t->ifp->nd);
|
||||
skb->dev = t->ifp->nd;
|
||||
}
|
||||
|
||||
@@ -401,6 +402,8 @@ aoecmd_ata_rw(struct aoedev *d)
|
||||
__skb_queue_head_init(&queue);
|
||||
__skb_queue_tail(&queue, skb);
|
||||
aoenet_xmit(&queue);
|
||||
} else {
|
||||
dev_put(f->t->ifp->nd);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -483,10 +486,13 @@ resend(struct aoedev *d, struct frame *f)
|
||||
memcpy(h->dst, t->addr, sizeof h->dst);
|
||||
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
|
||||
|
||||
dev_hold(t->ifp->nd);
|
||||
skb->dev = t->ifp->nd;
|
||||
skb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
if (skb == NULL) {
|
||||
dev_put(t->ifp->nd);
|
||||
return;
|
||||
}
|
||||
f->sent = ktime_get();
|
||||
__skb_queue_head_init(&queue);
|
||||
__skb_queue_tail(&queue, skb);
|
||||
@@ -617,6 +623,8 @@ probe(struct aoetgt *t)
|
||||
__skb_queue_head_init(&queue);
|
||||
__skb_queue_tail(&queue, skb);
|
||||
aoenet_xmit(&queue);
|
||||
} else {
|
||||
dev_put(f->t->ifp->nd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1395,6 +1403,7 @@ aoecmd_ata_id(struct aoedev *d)
|
||||
ah->cmdstat = ATA_CMD_ID_ATA;
|
||||
ah->lba3 = 0xa0;
|
||||
|
||||
dev_hold(t->ifp->nd);
|
||||
skb->dev = t->ifp->nd;
|
||||
|
||||
d->rttavg = RTTAVG_INIT;
|
||||
@@ -1404,6 +1413,8 @@ aoecmd_ata_id(struct aoedev *d)
|
||||
skb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb)
|
||||
f->sent = ktime_get();
|
||||
else
|
||||
dev_put(t->ifp->nd);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
@@ -531,6 +531,8 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe122), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek 8852BE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK |
|
||||
|
||||
@@ -2055,25 +2055,27 @@ static int virtcons_probe(struct virtio_device *vdev)
|
||||
multiport = true;
|
||||
}
|
||||
|
||||
err = init_vqs(portdev);
|
||||
if (err < 0) {
|
||||
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
|
||||
goto free_chrdev;
|
||||
}
|
||||
|
||||
spin_lock_init(&portdev->ports_lock);
|
||||
INIT_LIST_HEAD(&portdev->ports);
|
||||
INIT_LIST_HEAD(&portdev->list);
|
||||
|
||||
virtio_device_ready(portdev->vdev);
|
||||
|
||||
INIT_WORK(&portdev->config_work, &config_work_handler);
|
||||
INIT_WORK(&portdev->control_work, &control_work_handler);
|
||||
|
||||
if (multiport) {
|
||||
spin_lock_init(&portdev->c_ivq_lock);
|
||||
spin_lock_init(&portdev->c_ovq_lock);
|
||||
}
|
||||
|
||||
err = init_vqs(portdev);
|
||||
if (err < 0) {
|
||||
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
|
||||
goto free_chrdev;
|
||||
}
|
||||
|
||||
virtio_device_ready(portdev->vdev);
|
||||
|
||||
if (multiport) {
|
||||
err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
|
||||
if (err < 0) {
|
||||
dev_err(&vdev->dev,
|
||||
|
||||
@@ -1581,7 +1581,7 @@ static int __alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
|
||||
regmap_update_bits(pll->clkr.regmap, PLL_L_VAL(pll), LUCID_EVO_PLL_L_VAL_MASK, l);
|
||||
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
|
||||
|
||||
/* Latch the PLL input */
|
||||
|
||||
@@ -266,6 +266,8 @@ static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable)
|
||||
cmd_state = 0;
|
||||
}
|
||||
|
||||
cmd_state = min(cmd_state, BCM_TCS_CMD_VOTE_MASK);
|
||||
|
||||
if (c->last_sent_aggr_state != cmd_state) {
|
||||
cmd.addr = c->res_addr;
|
||||
cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state);
|
||||
|
||||
@@ -837,6 +837,7 @@ static struct clk_branch disp_cc_mdss_dp_link1_intf_clk = {
|
||||
&disp_cc_mdss_dp_link1_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
@@ -872,6 +873,7 @@ static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
|
||||
&disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
@@ -997,6 +999,7 @@ static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
|
||||
&disp_cc_mdss_mdp_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -143,6 +143,23 @@ static struct clk_alpha_pll gpll7 = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpll9 = {
|
||||
.offset = 0x1c000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
|
||||
.clkr = {
|
||||
.enable_reg = 0x52000,
|
||||
.enable_mask = BIT(9),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpll9",
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_fixed_trion_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map gcc_parent_map_0[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_GPLL0_OUT_MAIN, 1 },
|
||||
@@ -242,7 +259,7 @@ static const struct parent_map gcc_parent_map_7[] = {
|
||||
static const struct clk_parent_data gcc_parents_7[] = {
|
||||
{ .fw_name = "bi_tcxo", },
|
||||
{ .hw = &gpll0.clkr.hw },
|
||||
{ .name = "gppl9" },
|
||||
{ .hw = &gpll9.clkr.hw },
|
||||
{ .hw = &gpll4.clkr.hw },
|
||||
{ .hw = &gpll0_out_even.clkr.hw },
|
||||
};
|
||||
@@ -261,28 +278,6 @@ static const struct clk_parent_data gcc_parents_8[] = {
|
||||
{ .hw = &gpll0_out_even.clkr.hw },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
|
||||
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_cpuss_ahb_clk_src = {
|
||||
.cmd_rcgr = 0x48014,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.freq_tbl = ftbl_gcc_cpuss_ahb_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_cpuss_ahb_clk_src",
|
||||
.parent_data = gcc_parents_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parents_0),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
|
||||
@@ -917,7 +912,7 @@ static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
|
||||
F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2),
|
||||
F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
|
||||
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
|
||||
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
|
||||
F(202000000, P_GPLL9_OUT_MAIN, 4, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -940,9 +935,8 @@ static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = {
|
||||
F(400000, P_BI_TCXO, 12, 1, 4),
|
||||
F(9600000, P_BI_TCXO, 2, 0, 0),
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
|
||||
F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
|
||||
F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
|
||||
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1600,25 +1594,6 @@ static struct clk_branch gcc_cfg_noc_usb3_sec_axi_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
/* For CPUSS functionality the AHB clock needs to be left enabled */
|
||||
static struct clk_branch gcc_cpuss_ahb_clk = {
|
||||
.halt_reg = 0x48000,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x52004,
|
||||
.enable_mask = BIT(21),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_cpuss_ahb_clk",
|
||||
.parent_hws = (const struct clk_hw *[]){
|
||||
&gcc_cpuss_ahb_clk_src.clkr.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_cpuss_rbcpr_clk = {
|
||||
.halt_reg = 0x48008,
|
||||
.halt_check = BRANCH_HALT,
|
||||
@@ -3151,25 +3126,6 @@ static struct clk_branch gcc_sdcc4_apps_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
/* For CPUSS functionality the SYS NOC clock needs to be left enabled */
|
||||
static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
|
||||
.halt_reg = 0x4819c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x52004,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_sys_noc_cpuss_ahb_clk",
|
||||
.parent_hws = (const struct clk_hw *[]){
|
||||
&gcc_cpuss_ahb_clk_src.clkr.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_tsif_ahb_clk = {
|
||||
.halt_reg = 0x36004,
|
||||
.halt_check = BRANCH_HALT,
|
||||
@@ -4259,8 +4215,6 @@ static struct clk_regmap *gcc_sc8180x_clocks[] = {
|
||||
[GCC_CFG_NOC_USB3_MP_AXI_CLK] = &gcc_cfg_noc_usb3_mp_axi_clk.clkr,
|
||||
[GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
|
||||
[GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr,
|
||||
[GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr,
|
||||
[GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr,
|
||||
[GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr,
|
||||
[GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
|
||||
[GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
|
||||
@@ -4397,7 +4351,6 @@ static struct clk_regmap *gcc_sc8180x_clocks[] = {
|
||||
[GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr,
|
||||
[GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
|
||||
[GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr,
|
||||
[GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
|
||||
[GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr,
|
||||
[GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr,
|
||||
[GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
|
||||
@@ -4484,6 +4437,7 @@ static struct clk_regmap *gcc_sc8180x_clocks[] = {
|
||||
[GPLL1] = &gpll1.clkr,
|
||||
[GPLL4] = &gpll4.clkr,
|
||||
[GPLL7] = &gpll7.clkr,
|
||||
[GPLL9] = &gpll9.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_sc8180x_resets[] = {
|
||||
|
||||
@@ -3228,7 +3228,7 @@ static struct gdsc pcie_0_gdsc = {
|
||||
.pd = {
|
||||
.name = "pcie_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
};
|
||||
|
||||
static struct gdsc pcie_1_gdsc = {
|
||||
@@ -3236,7 +3236,7 @@ static struct gdsc pcie_1_gdsc = {
|
||||
.pd = {
|
||||
.name = "pcie_1_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
};
|
||||
|
||||
static struct gdsc pcie_2_gdsc = {
|
||||
@@ -3244,7 +3244,7 @@ static struct gdsc pcie_2_gdsc = {
|
||||
.pd = {
|
||||
.name = "pcie_2_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
};
|
||||
|
||||
static struct gdsc ufs_card_gdsc = {
|
||||
|
||||
@@ -2934,7 +2934,7 @@ static struct gdsc pcie_0_gdsc = {
|
||||
.pd = {
|
||||
.name = "pcie_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
};
|
||||
|
||||
static struct gdsc pcie_1_gdsc = {
|
||||
@@ -2942,7 +2942,7 @@ static struct gdsc pcie_1_gdsc = {
|
||||
.pd = {
|
||||
.name = "pcie_1_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
};
|
||||
|
||||
static struct gdsc ufs_phy_gdsc = {
|
||||
|
||||
@@ -438,12 +438,13 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
|
||||
struct rockchip_clk_branch *list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
struct clk *clk = NULL;
|
||||
struct clk *clk;
|
||||
unsigned int idx;
|
||||
unsigned long flags;
|
||||
|
||||
for (idx = 0; idx < nr_clk; idx++, list++) {
|
||||
flags = list->flags;
|
||||
clk = NULL;
|
||||
|
||||
/* catch simple muxes */
|
||||
switch (list->branch_type) {
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
#include "clk.h"
|
||||
#include "clk-exynos-arm64.h"
|
||||
|
||||
/* NOTE: Must be equal to the last clock ID increased by one */
|
||||
#define CLKS_NR_TOP (CLK_GOUT_FSYS_USB30DRD + 1)
|
||||
#define CLKS_NR_CORE (CLK_GOUT_TREX_P_CORE_PCLK_P_CORE + 1)
|
||||
#define CLKS_NR_PERI (CLK_GOUT_WDT1_PCLK + 1)
|
||||
#define CLKS_NR_FSYS (CLK_MOUT_FSYS_USB30DRD_USER + 1)
|
||||
|
||||
/* ---- CMU_TOP ------------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_TOP (0x12060000) */
|
||||
@@ -334,7 +340,7 @@ static const struct samsung_cmu_info top_cmu_info __initconst = {
|
||||
.nr_div_clks = ARRAY_SIZE(top_div_clks),
|
||||
.gate_clks = top_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(top_gate_clks),
|
||||
.nr_clk_ids = TOP_NR_CLK,
|
||||
.nr_clk_ids = CLKS_NR_TOP,
|
||||
.clk_regs = top_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(top_clk_regs),
|
||||
};
|
||||
@@ -553,7 +559,7 @@ static const struct samsung_cmu_info peri_cmu_info __initconst = {
|
||||
.nr_mux_clks = ARRAY_SIZE(peri_mux_clks),
|
||||
.gate_clks = peri_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(peri_gate_clks),
|
||||
.nr_clk_ids = PERI_NR_CLK,
|
||||
.nr_clk_ids = CLKS_NR_PERI,
|
||||
.clk_regs = peri_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(peri_clk_regs),
|
||||
.clk_name = "dout_peri_bus",
|
||||
@@ -662,7 +668,7 @@ static const struct samsung_cmu_info core_cmu_info __initconst = {
|
||||
.nr_div_clks = ARRAY_SIZE(core_div_clks),
|
||||
.gate_clks = core_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(core_gate_clks),
|
||||
.nr_clk_ids = CORE_NR_CLK,
|
||||
.nr_clk_ids = CLKS_NR_CORE,
|
||||
.clk_regs = core_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(core_clk_regs),
|
||||
.clk_name = "dout_core_bus",
|
||||
@@ -744,7 +750,7 @@ static const struct samsung_cmu_info fsys_cmu_info __initconst = {
|
||||
.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks),
|
||||
.gate_clks = fsys_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(fsys_gate_clks),
|
||||
.nr_clk_ids = FSYS_NR_CLK,
|
||||
.nr_clk_ids = CLKS_NR_FSYS,
|
||||
.clk_regs = fsys_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs),
|
||||
.clk_name = "dout_fsys_bus",
|
||||
|
||||
@@ -1596,7 +1596,7 @@ static void intel_pstate_notify_work(struct work_struct *work)
|
||||
wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0);
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(hwp_notify_lock);
|
||||
static DEFINE_RAW_SPINLOCK(hwp_notify_lock);
|
||||
static cpumask_t hwp_intr_enable_mask;
|
||||
|
||||
void notify_hwp_interrupt(void)
|
||||
@@ -1613,7 +1613,7 @@ void notify_hwp_interrupt(void)
|
||||
if (!(value & 0x01))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&hwp_notify_lock, flags);
|
||||
raw_spin_lock_irqsave(&hwp_notify_lock, flags);
|
||||
|
||||
if (!cpumask_test_cpu(this_cpu, &hwp_intr_enable_mask))
|
||||
goto ack_intr;
|
||||
@@ -1637,13 +1637,13 @@ void notify_hwp_interrupt(void)
|
||||
|
||||
schedule_delayed_work(&cpudata->hwp_notify_work, msecs_to_jiffies(10));
|
||||
|
||||
spin_unlock_irqrestore(&hwp_notify_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
|
||||
|
||||
return;
|
||||
|
||||
ack_intr:
|
||||
wrmsrl_safe(MSR_HWP_STATUS, 0);
|
||||
spin_unlock_irqrestore(&hwp_notify_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
|
||||
}
|
||||
|
||||
static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata)
|
||||
@@ -1656,10 +1656,10 @@ static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata)
|
||||
/* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */
|
||||
wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00);
|
||||
|
||||
spin_lock_irqsave(&hwp_notify_lock, flags);
|
||||
raw_spin_lock_irqsave(&hwp_notify_lock, flags);
|
||||
if (cpumask_test_and_clear_cpu(cpudata->cpu, &hwp_intr_enable_mask))
|
||||
cancel_delayed_work(&cpudata->hwp_notify_work);
|
||||
spin_unlock_irqrestore(&hwp_notify_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
|
||||
}
|
||||
|
||||
static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)
|
||||
@@ -1668,10 +1668,10 @@ static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)
|
||||
if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&hwp_notify_lock, flags);
|
||||
raw_spin_lock_irqsave(&hwp_notify_lock, flags);
|
||||
INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work);
|
||||
cpumask_set_cpu(cpudata->cpu, &hwp_intr_enable_mask);
|
||||
spin_unlock_irqrestore(&hwp_notify_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
|
||||
|
||||
/* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */
|
||||
wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x01);
|
||||
@@ -3101,10 +3101,10 @@ static void intel_pstate_driver_cleanup(void)
|
||||
if (intel_pstate_driver == &intel_pstate)
|
||||
intel_pstate_clear_update_util_hook(cpu);
|
||||
|
||||
spin_lock(&hwp_notify_lock);
|
||||
raw_spin_lock(&hwp_notify_lock);
|
||||
kfree(all_cpu_data[cpu]);
|
||||
WRITE_ONCE(all_cpu_data[cpu], NULL);
|
||||
spin_unlock(&hwp_notify_lock);
|
||||
raw_spin_unlock(&hwp_notify_lock);
|
||||
}
|
||||
}
|
||||
cpus_read_unlock();
|
||||
|
||||
@@ -25,12 +25,6 @@
|
||||
#define MSG_RING BIT(1)
|
||||
#define TAG_SZ 32
|
||||
|
||||
static inline struct tegra_bpmp *
|
||||
mbox_client_to_bpmp(struct mbox_client *client)
|
||||
{
|
||||
return container_of(client, struct tegra_bpmp, mbox.client);
|
||||
}
|
||||
|
||||
static inline const struct tegra_bpmp_ops *
|
||||
channel_to_ops(struct tegra_bpmp_channel *channel)
|
||||
{
|
||||
|
||||
@@ -295,7 +295,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
|
||||
* serve as EDMA event triggers.
|
||||
*/
|
||||
|
||||
static void gpio_irq_disable(struct irq_data *d)
|
||||
static void gpio_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct davinci_gpio_regs __iomem *g = irq2regs(d);
|
||||
uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
|
||||
@@ -304,7 +304,7 @@ static void gpio_irq_disable(struct irq_data *d)
|
||||
writel_relaxed(mask, &g->clr_rising);
|
||||
}
|
||||
|
||||
static void gpio_irq_enable(struct irq_data *d)
|
||||
static void gpio_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct davinci_gpio_regs __iomem *g = irq2regs(d);
|
||||
uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
|
||||
@@ -330,8 +330,8 @@ static int gpio_irq_type(struct irq_data *d, unsigned trigger)
|
||||
|
||||
static struct irq_chip gpio_irqchip = {
|
||||
.name = "GPIO",
|
||||
.irq_enable = gpio_irq_enable,
|
||||
.irq_disable = gpio_irq_disable,
|
||||
.irq_unmask = gpio_irq_unmask,
|
||||
.irq_mask = gpio_irq_mask,
|
||||
.irq_set_type = gpio_irq_type,
|
||||
.flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
@@ -257,6 +257,10 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
|
||||
if (size < sizeof(struct drm_amdgpu_bo_list_in))
|
||||
goto free_partial_kdata;
|
||||
|
||||
/* Only a single BO list is allowed to simplify handling. */
|
||||
if (p->bo_list)
|
||||
ret = -EINVAL;
|
||||
|
||||
ret = amdgpu_cs_p1_bo_handles(p, p->chunks[i].kdata);
|
||||
if (ret)
|
||||
goto free_partial_kdata;
|
||||
|
||||
@@ -676,8 +676,11 @@ int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *r
|
||||
int r;
|
||||
|
||||
if (amdgpu_ras_is_supported(adev, ras_block->block)) {
|
||||
if (!amdgpu_persistent_edc_harvesting_supported(adev))
|
||||
amdgpu_ras_reset_error_status(adev, AMDGPU_RAS_BLOCK__GFX);
|
||||
if (!amdgpu_persistent_edc_harvesting_supported(adev)) {
|
||||
r = amdgpu_ras_reset_error_status(adev, AMDGPU_RAS_BLOCK__GFX);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_ras_block_late_init(adev, ras_block);
|
||||
if (r)
|
||||
@@ -758,7 +761,10 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
||||
pr_err("critical bug! too many kiq readers\n");
|
||||
goto failed_unlock;
|
||||
}
|
||||
amdgpu_ring_alloc(ring, 32);
|
||||
r = amdgpu_ring_alloc(ring, 32);
|
||||
if (r)
|
||||
goto failed_unlock;
|
||||
|
||||
amdgpu_ring_emit_rreg(ring, reg, reg_val_offs);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r)
|
||||
@@ -824,7 +830,10 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
amdgpu_ring_alloc(ring, 32);
|
||||
r = amdgpu_ring_alloc(ring, 32);
|
||||
if (r)
|
||||
goto failed_unlock;
|
||||
|
||||
amdgpu_ring_emit_wreg(ring, reg, v);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r)
|
||||
@@ -860,6 +869,7 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
|
||||
|
||||
failed_undo:
|
||||
amdgpu_ring_undo(ring);
|
||||
failed_unlock:
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
failed_kiq_write:
|
||||
dev_err(adev->dev, "failed to write reg:%x\n", reg);
|
||||
|
||||
@@ -1173,6 +1173,10 @@ static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = {
|
||||
{ 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc6 },
|
||||
/* Apple MacBook Pro (15-inch, 2019) Radeon Pro Vega 20 4 GB */
|
||||
{ 0x1002, 0x69af, 0x106b, 0x019a, 0xc0 },
|
||||
/* https://bbs.openkylin.top/t/topic/171497 */
|
||||
{ 0x1002, 0x15d8, 0x19e5, 0x3e14, 0xc2 },
|
||||
/* HP 705G4 DM with R5 2400G */
|
||||
{ 0x1002, 0x15dd, 0x103c, 0x8464, 0xd6 },
|
||||
{ 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
@@ -890,6 +890,7 @@ exit:
|
||||
pr_debug("Queue id %d was restored successfully\n", queue_id);
|
||||
|
||||
kfree(q_data);
|
||||
kfree(q_extra_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -712,6 +712,12 @@ static void dmub_hpd_callback(struct amdgpu_device *adev,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Skip DMUB HPD IRQ in suspend/resume. We will probe them later. */
|
||||
if (notify->type == DMUB_NOTIFICATION_HPD && adev->in_suspend) {
|
||||
DRM_INFO("Skip DMUB HPD IRQ callback in suspend/resume\n");
|
||||
return;
|
||||
}
|
||||
|
||||
link_index = notify->link_index;
|
||||
link = adev->dm.dc->links[link_index];
|
||||
dev = adev->dm.ddev;
|
||||
@@ -4071,7 +4077,7 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm,
|
||||
int spread = caps.max_input_signal - caps.min_input_signal;
|
||||
|
||||
if (caps.max_input_signal > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT ||
|
||||
caps.min_input_signal < AMDGPU_DM_DEFAULT_MIN_BACKLIGHT ||
|
||||
caps.min_input_signal < 0 ||
|
||||
spread > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT ||
|
||||
spread < AMDGPU_DM_MIN_SPREAD) {
|
||||
DRM_DEBUG_KMS("DM: Invalid backlight caps: min=%d, max=%d\n",
|
||||
|
||||
@@ -1281,7 +1281,8 @@ void handle_cursor_update(struct drm_plane *plane,
|
||||
adev->dm.dc->caps.color.dpp.gamma_corr)
|
||||
attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1;
|
||||
|
||||
attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
|
||||
if (afb)
|
||||
attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
|
||||
|
||||
if (crtc_state->stream) {
|
||||
mutex_lock(&adev->dm.dc_lock);
|
||||
|
||||
@@ -3727,7 +3727,8 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||
}
|
||||
|
||||
if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
|
||||
if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
|
||||
if (top_pipe_to_program &&
|
||||
top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
|
||||
top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
|
||||
top_pipe_to_program->stream_res.tg,
|
||||
CRTC_STATE_VACTIVE);
|
||||
@@ -4515,7 +4516,8 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
|
||||
if (allow == dc->idle_optimizations_allowed)
|
||||
return;
|
||||
|
||||
if (dc->hwss.apply_idle_power_optimizations && dc->hwss.apply_idle_power_optimizations(dc, allow))
|
||||
if (dc->hwss.apply_idle_power_optimizations && dc->clk_mgr != NULL &&
|
||||
dc->hwss.apply_idle_power_optimizations(dc, allow))
|
||||
dc->idle_optimizations_allowed = allow;
|
||||
}
|
||||
|
||||
|
||||
@@ -1915,6 +1915,8 @@ static bool are_stream_backends_same(
|
||||
bool dc_is_stream_unchanged(
|
||||
struct dc_stream_state *old_stream, struct dc_stream_state *stream)
|
||||
{
|
||||
if (!old_stream || !stream)
|
||||
return false;
|
||||
|
||||
if (!are_stream_backends_same(old_stream, stream))
|
||||
return false;
|
||||
@@ -2634,8 +2636,10 @@ static bool planes_changed_for_existing_stream(struct dc_state *context,
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream_status)
|
||||
if (!stream_status) {
|
||||
ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < set_count; i++)
|
||||
if (set[i].stream == stream)
|
||||
|
||||
@@ -571,6 +571,8 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
|
||||
i += increment) {
|
||||
if (j == hw_points - 1)
|
||||
break;
|
||||
if (i >= TRANSFER_FUNC_POINTS)
|
||||
return false;
|
||||
rgb_resulted[j].red = output_tf->tf_pts.red[i];
|
||||
rgb_resulted[j].green = output_tf->tf_pts.green[i];
|
||||
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
|
||||
|
||||
@@ -178,6 +178,8 @@ bool cm3_helper_translate_curve_to_hw_format(
|
||||
i += increment) {
|
||||
if (j == hw_points - 1)
|
||||
break;
|
||||
if (i >= TRANSFER_FUNC_POINTS)
|
||||
return false;
|
||||
rgb_resulted[j].red = output_tf->tf_pts.red[i];
|
||||
rgb_resulted[j].green = output_tf->tf_pts.green[i];
|
||||
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
|
||||
@@ -355,6 +357,8 @@ bool cm3_helper_translate_curve_to_degamma_hw_format(
|
||||
i += increment) {
|
||||
if (j == hw_points - 1)
|
||||
break;
|
||||
if (i >= TRANSFER_FUNC_POINTS)
|
||||
return false;
|
||||
rgb_resulted[j].red = output_tf->tf_pts.red[i];
|
||||
rgb_resulted[j].green = output_tf->tf_pts.green[i];
|
||||
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
|
||||
|
||||
@@ -78,7 +78,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
|
||||
|
||||
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
|
||||
{
|
||||
unsigned int ret_val = 0;
|
||||
unsigned int ret_val = 1;
|
||||
|
||||
if (source_format == dm_444_16) {
|
||||
if (!is_chroma)
|
||||
|
||||
@@ -53,7 +53,7 @@ static void calculate_ttu_cursor(
|
||||
|
||||
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
|
||||
{
|
||||
unsigned int ret_val = 0;
|
||||
unsigned int ret_val = 1;
|
||||
|
||||
if (source_format == dm_444_16) {
|
||||
if (!is_chroma)
|
||||
|
||||
@@ -1185,6 +1185,8 @@ static int init_overdrive_limits(struct pp_hwmgr *hwmgr,
|
||||
fw_info = smu_atom_get_data_table(hwmgr->adev,
|
||||
GetIndexIntoMasterTable(DATA, FirmwareInfo),
|
||||
&size, &frev, &crev);
|
||||
PP_ASSERT_WITH_CODE(fw_info != NULL,
|
||||
"Missing firmware info!", return -EINVAL);
|
||||
|
||||
if ((fw_info->ucTableFormatRevision == 1)
|
||||
&& (le16_to_cpu(fw_info->usStructureSize) >= sizeof(ATOM_FIRMWARE_INFO_V1_4)))
|
||||
|
||||
@@ -567,7 +567,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
|
||||
&state->fb_damage_clips,
|
||||
val,
|
||||
-1,
|
||||
sizeof(struct drm_rect),
|
||||
sizeof(struct drm_mode_rect),
|
||||
&replaced);
|
||||
return ret;
|
||||
} else if (property == plane->scaling_filter_property) {
|
||||
|
||||
@@ -904,6 +904,7 @@ out:
|
||||
connector_set = NULL;
|
||||
fb = NULL;
|
||||
mode = NULL;
|
||||
num_connectors = 0;
|
||||
|
||||
DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
|
||||
|
||||
|
||||
@@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str)
|
||||
copy = iterator->remain;
|
||||
|
||||
/* Copy out the bit of the string that we need */
|
||||
memcpy(iterator->data,
|
||||
str + (iterator->start - iterator->offset), copy);
|
||||
if (iterator->data)
|
||||
memcpy(iterator->data,
|
||||
str + (iterator->start - iterator->offset), copy);
|
||||
|
||||
iterator->offset = iterator->start + copy;
|
||||
iterator->remain -= copy;
|
||||
@@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str)
|
||||
|
||||
len = min_t(ssize_t, strlen(str), iterator->remain);
|
||||
|
||||
memcpy(iterator->data + pos, str, len);
|
||||
if (iterator->data)
|
||||
memcpy(iterator->data + pos, str, len);
|
||||
|
||||
iterator->offset += len;
|
||||
iterator->remain -= len;
|
||||
@@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
|
||||
if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
|
||||
ssize_t pos = iterator->offset - iterator->start;
|
||||
|
||||
snprintf(((char *) iterator->data) + pos,
|
||||
iterator->remain, "%pV", vaf);
|
||||
if (iterator->data)
|
||||
snprintf(((char *) iterator->data) + pos,
|
||||
iterator->remain, "%pV", vaf);
|
||||
|
||||
iterator->offset += len;
|
||||
iterator->remain -= len;
|
||||
|
||||
@@ -1058,7 +1058,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf)
|
||||
spin_unlock(&to_i915(obj->base.dev)->runtime_pm.lmem_userfault_lock);
|
||||
}
|
||||
|
||||
if (wakeref & CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
|
||||
if (wakeref && CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND != 0)
|
||||
intel_wakeref_auto(&to_i915(obj->base.dev)->runtime_pm.userfault_wakeref,
|
||||
msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
|
||||
|
||||
|
||||
@@ -746,6 +746,10 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
|
||||
soc = soc_device_match(omapdrm_soc_devices);
|
||||
priv->omaprev = soc ? (uintptr_t)soc->data : 0;
|
||||
priv->wq = alloc_ordered_workqueue("omapdrm", 0);
|
||||
if (!priv->wq) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc_workqueue;
|
||||
}
|
||||
|
||||
mutex_init(&priv->list_lock);
|
||||
INIT_LIST_HEAD(&priv->obj_list);
|
||||
@@ -808,6 +812,7 @@ err_gem_deinit:
|
||||
drm_mode_config_cleanup(ddev);
|
||||
omap_gem_deinit(ddev);
|
||||
destroy_workqueue(priv->wq);
|
||||
err_alloc_workqueue:
|
||||
omap_disconnect_pipelines(ddev);
|
||||
drm_dev_put(ddev);
|
||||
return ret;
|
||||
|
||||
@@ -1015,45 +1015,65 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
|
||||
|
||||
DRM_DEBUG_KMS("\n");
|
||||
|
||||
if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
|
||||
(rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
|
||||
(rdev->family == CHIP_RS200)) {
|
||||
switch (rdev->family) {
|
||||
case CHIP_R100:
|
||||
case CHIP_RV100:
|
||||
case CHIP_RV200:
|
||||
case CHIP_RS100:
|
||||
case CHIP_RS200:
|
||||
DRM_INFO("Loading R100 Microcode\n");
|
||||
fw_name = FIRMWARE_R100;
|
||||
} else if ((rdev->family == CHIP_R200) ||
|
||||
(rdev->family == CHIP_RV250) ||
|
||||
(rdev->family == CHIP_RV280) ||
|
||||
(rdev->family == CHIP_RS300)) {
|
||||
break;
|
||||
|
||||
case CHIP_R200:
|
||||
case CHIP_RV250:
|
||||
case CHIP_RV280:
|
||||
case CHIP_RS300:
|
||||
DRM_INFO("Loading R200 Microcode\n");
|
||||
fw_name = FIRMWARE_R200;
|
||||
} else if ((rdev->family == CHIP_R300) ||
|
||||
(rdev->family == CHIP_R350) ||
|
||||
(rdev->family == CHIP_RV350) ||
|
||||
(rdev->family == CHIP_RV380) ||
|
||||
(rdev->family == CHIP_RS400) ||
|
||||
(rdev->family == CHIP_RS480)) {
|
||||
break;
|
||||
|
||||
case CHIP_R300:
|
||||
case CHIP_R350:
|
||||
case CHIP_RV350:
|
||||
case CHIP_RV380:
|
||||
case CHIP_RS400:
|
||||
case CHIP_RS480:
|
||||
DRM_INFO("Loading R300 Microcode\n");
|
||||
fw_name = FIRMWARE_R300;
|
||||
} else if ((rdev->family == CHIP_R420) ||
|
||||
(rdev->family == CHIP_R423) ||
|
||||
(rdev->family == CHIP_RV410)) {
|
||||
break;
|
||||
|
||||
case CHIP_R420:
|
||||
case CHIP_R423:
|
||||
case CHIP_RV410:
|
||||
DRM_INFO("Loading R400 Microcode\n");
|
||||
fw_name = FIRMWARE_R420;
|
||||
} else if ((rdev->family == CHIP_RS690) ||
|
||||
(rdev->family == CHIP_RS740)) {
|
||||
break;
|
||||
|
||||
case CHIP_RS690:
|
||||
case CHIP_RS740:
|
||||
DRM_INFO("Loading RS690/RS740 Microcode\n");
|
||||
fw_name = FIRMWARE_RS690;
|
||||
} else if (rdev->family == CHIP_RS600) {
|
||||
break;
|
||||
|
||||
case CHIP_RS600:
|
||||
DRM_INFO("Loading RS600 Microcode\n");
|
||||
fw_name = FIRMWARE_RS600;
|
||||
} else if ((rdev->family == CHIP_RV515) ||
|
||||
(rdev->family == CHIP_R520) ||
|
||||
(rdev->family == CHIP_RV530) ||
|
||||
(rdev->family == CHIP_R580) ||
|
||||
(rdev->family == CHIP_RV560) ||
|
||||
(rdev->family == CHIP_RV570)) {
|
||||
break;
|
||||
|
||||
case CHIP_RV515:
|
||||
case CHIP_R520:
|
||||
case CHIP_RV530:
|
||||
case CHIP_R580:
|
||||
case CHIP_RV560:
|
||||
case CHIP_RV570:
|
||||
DRM_INFO("Loading R500 Microcode\n");
|
||||
fw_name = FIRMWARE_R520;
|
||||
break;
|
||||
|
||||
default:
|
||||
DRM_ERROR("Unsupported Radeon family %u\n", rdev->family);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
|
||||
|
||||
@@ -1559,6 +1559,10 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
VOP_AFBC_SET(vop, enable, s->enable_afbc);
|
||||
vop_cfg_done(vop);
|
||||
|
||||
/* Ack the DMA transfer of the previous frame (RK3066). */
|
||||
if (VOP_HAS_REG(vop, common, dma_stop))
|
||||
VOP_REG_SET(vop, common, dma_stop, 0);
|
||||
|
||||
spin_unlock(&vop->reg_lock);
|
||||
|
||||
/*
|
||||
|
||||
@@ -117,6 +117,7 @@ struct vop_common {
|
||||
struct vop_reg lut_buffer_index;
|
||||
struct vop_reg gate_en;
|
||||
struct vop_reg mmu_en;
|
||||
struct vop_reg dma_stop;
|
||||
struct vop_reg out_mode;
|
||||
struct vop_reg standby;
|
||||
};
|
||||
|
||||
@@ -431,6 +431,7 @@ static const struct vop_output rk3066_output = {
|
||||
};
|
||||
|
||||
static const struct vop_common rk3066_common = {
|
||||
.dma_stop = VOP_REG(RK3066_SYS_CTRL0, 0x1, 0),
|
||||
.standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
|
||||
.out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
|
||||
.cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
|
||||
|
||||
@@ -110,8 +110,10 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
|
||||
{
|
||||
WARN_ON(!num_sched_list || !sched_list);
|
||||
|
||||
spin_lock(&entity->rq_lock);
|
||||
entity->sched_list = sched_list;
|
||||
entity->num_sched_list = num_sched_list;
|
||||
spin_unlock(&entity->rq_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_sched_entity_modify_sched);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <drm/drm_module.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/drm_managed.h>
|
||||
|
||||
#include "ltdc.h"
|
||||
|
||||
@@ -74,7 +75,7 @@ static int drv_load(struct drm_device *ddev)
|
||||
|
||||
DRM_DEBUG("%s\n", __func__);
|
||||
|
||||
ldev = devm_kzalloc(ddev->dev, sizeof(*ldev), GFP_KERNEL);
|
||||
ldev = drmm_kzalloc(ddev, sizeof(*ldev), GFP_KERNEL);
|
||||
if (!ldev)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/drm_simple_kms_helper.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/drm_managed.h>
|
||||
|
||||
#include <video/videomode.h>
|
||||
|
||||
@@ -1200,7 +1201,6 @@ static void ltdc_crtc_atomic_print_state(struct drm_printer *p,
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs ltdc_crtc_funcs = {
|
||||
.destroy = drm_crtc_cleanup,
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.reset = drm_atomic_helper_crtc_reset,
|
||||
@@ -1213,7 +1213,6 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = {
|
||||
};
|
||||
|
||||
static const struct drm_crtc_funcs ltdc_crtc_with_crc_support_funcs = {
|
||||
.destroy = drm_crtc_cleanup,
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.reset = drm_atomic_helper_crtc_reset,
|
||||
@@ -1515,6 +1514,9 @@ static void ltdc_plane_atomic_disable(struct drm_plane *plane,
|
||||
/* Disable layer */
|
||||
regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN | LXCR_CLUTEN | LXCR_HMEN, 0);
|
||||
|
||||
/* Reset the layer transparency to hide any related background color */
|
||||
regmap_write_bits(ldev->regmap, LTDC_L1CACR + lofs, LXCACR_CONSTA, 0x00);
|
||||
|
||||
/* Commit shadow registers = update plane at next vblank */
|
||||
if (ldev->caps.plane_reg_shadow)
|
||||
regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
|
||||
@@ -1546,7 +1548,6 @@ static void ltdc_plane_atomic_print_state(struct drm_printer *p,
|
||||
static const struct drm_plane_funcs ltdc_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.destroy = drm_plane_cleanup,
|
||||
.reset = drm_atomic_helper_plane_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||
@@ -1573,7 +1574,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
|
||||
const u64 *modifiers = ltdc_format_modifiers;
|
||||
u32 lofs = index * LAY_OFS;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
/* Allocate the biggest size according to supported color formats */
|
||||
formats = devm_kzalloc(dev, (ldev->caps.pix_fmt_nb +
|
||||
@@ -1616,14 +1616,10 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
|
||||
}
|
||||
}
|
||||
|
||||
plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL);
|
||||
if (!plane)
|
||||
return NULL;
|
||||
|
||||
ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
|
||||
<dc_plane_funcs, formats, nb_fmt,
|
||||
modifiers, type, NULL);
|
||||
if (ret < 0)
|
||||
plane = drmm_universal_plane_alloc(ddev, struct drm_plane, dev,
|
||||
possible_crtcs, <dc_plane_funcs, formats,
|
||||
nb_fmt, modifiers, type, NULL);
|
||||
if (IS_ERR(plane))
|
||||
return NULL;
|
||||
|
||||
if (ldev->caps.ycbcr_input) {
|
||||
@@ -1646,15 +1642,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
|
||||
return plane;
|
||||
}
|
||||
|
||||
static void ltdc_plane_destroy_all(struct drm_device *ddev)
|
||||
{
|
||||
struct drm_plane *plane, *plane_temp;
|
||||
|
||||
list_for_each_entry_safe(plane, plane_temp,
|
||||
&ddev->mode_config.plane_list, head)
|
||||
drm_plane_cleanup(plane);
|
||||
}
|
||||
|
||||
static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
|
||||
{
|
||||
struct ltdc_device *ldev = ddev->dev_private;
|
||||
@@ -1680,14 +1667,14 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
|
||||
|
||||
/* Init CRTC according to its hardware features */
|
||||
if (ldev->caps.crc)
|
||||
ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
|
||||
<dc_crtc_with_crc_support_funcs, NULL);
|
||||
ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL,
|
||||
<dc_crtc_with_crc_support_funcs, NULL);
|
||||
else
|
||||
ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
|
||||
<dc_crtc_funcs, NULL);
|
||||
ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL,
|
||||
<dc_crtc_funcs, NULL);
|
||||
if (ret) {
|
||||
DRM_ERROR("Can not initialize CRTC\n");
|
||||
goto cleanup;
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_crtc_helper_add(crtc, <dc_crtc_helper_funcs);
|
||||
@@ -1701,9 +1688,8 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
|
||||
for (i = 1; i < ldev->caps.nb_layers; i++) {
|
||||
overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY, i);
|
||||
if (!overlay) {
|
||||
ret = -ENOMEM;
|
||||
DRM_ERROR("Can not create overlay plane %d\n", i);
|
||||
goto cleanup;
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (ldev->caps.dynamic_zorder)
|
||||
drm_plane_create_zpos_property(overlay, i, 0, ldev->caps.nb_layers - 1);
|
||||
@@ -1716,10 +1702,6 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
ltdc_plane_destroy_all(ddev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ltdc_encoder_disable(struct drm_encoder *encoder)
|
||||
@@ -1779,23 +1761,19 @@ static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge)
|
||||
struct drm_encoder *encoder;
|
||||
int ret;
|
||||
|
||||
encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
|
||||
if (!encoder)
|
||||
return -ENOMEM;
|
||||
encoder = drmm_simple_encoder_alloc(ddev, struct drm_encoder, dev,
|
||||
DRM_MODE_ENCODER_DPI);
|
||||
if (IS_ERR(encoder))
|
||||
return PTR_ERR(encoder);
|
||||
|
||||
encoder->possible_crtcs = CRTC_MASK;
|
||||
encoder->possible_clones = 0; /* No cloning support */
|
||||
|
||||
drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI);
|
||||
|
||||
drm_encoder_helper_add(encoder, <dc_encoder_helper_funcs);
|
||||
|
||||
ret = drm_bridge_attach(encoder, bridge, NULL, 0);
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
drm_encoder_cleanup(encoder);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);
|
||||
|
||||
@@ -1965,8 +1943,7 @@ int ltdc_load(struct drm_device *ddev)
|
||||
goto err;
|
||||
|
||||
if (panel) {
|
||||
bridge = drm_panel_bridge_add_typed(panel,
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
bridge = drmm_panel_bridge_add(ddev, panel);
|
||||
if (IS_ERR(bridge)) {
|
||||
DRM_ERROR("panel-bridge endpoint %d\n", i);
|
||||
ret = PTR_ERR(bridge);
|
||||
@@ -2048,7 +2025,7 @@ int ltdc_load(struct drm_device *ddev)
|
||||
}
|
||||
}
|
||||
|
||||
crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
|
||||
crtc = drmm_kzalloc(ddev, sizeof(*crtc), GFP_KERNEL);
|
||||
if (!crtc) {
|
||||
DRM_ERROR("Failed to allocate crtc\n");
|
||||
ret = -ENOMEM;
|
||||
@@ -2075,9 +2052,6 @@ int ltdc_load(struct drm_device *ddev)
|
||||
|
||||
return 0;
|
||||
err:
|
||||
for (i = 0; i < nb_endpoints; i++)
|
||||
drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i);
|
||||
|
||||
clk_disable_unprepare(ldev->pixel_clk);
|
||||
|
||||
return ret;
|
||||
@@ -2085,16 +2059,8 @@ err:
|
||||
|
||||
void ltdc_unload(struct drm_device *ddev)
|
||||
{
|
||||
struct device *dev = ddev->dev;
|
||||
int nb_endpoints, i;
|
||||
|
||||
DRM_DEBUG_DRIVER("\n");
|
||||
|
||||
nb_endpoints = of_graph_get_endpoint_count(dev->of_node);
|
||||
|
||||
for (i = 0; i < nb_endpoints; i++)
|
||||
drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i);
|
||||
|
||||
pm_runtime_disable(ddev->dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -786,6 +786,7 @@
|
||||
#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3
|
||||
#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5
|
||||
#define USB_DEVICE_ID_LENOVO_X12_TAB 0x60fe
|
||||
#define USB_DEVICE_ID_LENOVO_X12_TAB2 0x61ae
|
||||
#define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E 0x600e
|
||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d
|
||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
|
||||
|
||||
@@ -2116,6 +2116,12 @@ static const struct hid_device_id mt_devices[] = {
|
||||
USB_VENDOR_ID_LENOVO,
|
||||
USB_DEVICE_ID_LENOVO_X12_TAB) },
|
||||
|
||||
/* Lenovo X12 TAB Gen 2 */
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
|
||||
HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_LENOVO,
|
||||
USB_DEVICE_ID_LENOVO_X12_TAB2) },
|
||||
|
||||
/* Logitech devices */
|
||||
{ .driver_data = MT_CLS_NSMU,
|
||||
HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
|
||||
@@ -2353,7 +2353,7 @@ static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev)
|
||||
struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
|
||||
|
||||
if (!stm32f7_i2c_is_slave_registered(i2c_dev))
|
||||
clk_disable_unprepare(i2c_dev->clk);
|
||||
clk_disable(i2c_dev->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2364,9 +2364,9 @@ static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev)
|
||||
int ret;
|
||||
|
||||
if (!stm32f7_i2c_is_slave_registered(i2c_dev)) {
|
||||
ret = clk_prepare_enable(i2c_dev->clk);
|
||||
ret = clk_enable(i2c_dev->clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to prepare_enable clock\n");
|
||||
dev_err(dev, "failed to enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,14 +482,17 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
|
||||
goto out;
|
||||
}
|
||||
|
||||
xiic_fill_tx_fifo(i2c);
|
||||
|
||||
/* current message sent and there is space in the fifo */
|
||||
if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) {
|
||||
if (xiic_tx_space(i2c)) {
|
||||
xiic_fill_tx_fifo(i2c);
|
||||
} else {
|
||||
/* current message fully written */
|
||||
dev_dbg(i2c->adap.dev.parent,
|
||||
"%s end of message sent, nmsgs: %d\n",
|
||||
__func__, i2c->nmsgs);
|
||||
if (i2c->nmsgs > 1) {
|
||||
/* Don't move onto the next message until the TX FIFO empties,
|
||||
* to ensure that a NAK is not missed.
|
||||
*/
|
||||
if (i2c->nmsgs > 1 && (pend & XIIC_INTR_TX_EMPTY_MASK)) {
|
||||
i2c->nmsgs--;
|
||||
i2c->tx_msg++;
|
||||
xfer_more = 1;
|
||||
@@ -500,11 +503,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
|
||||
"%s Got TX IRQ but no more to do...\n",
|
||||
__func__);
|
||||
}
|
||||
} else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1))
|
||||
/* current frame is sent and is last,
|
||||
* make sure to disable tx half
|
||||
*/
|
||||
xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
if (pend & XIIC_INTR_BNB_MASK) {
|
||||
@@ -799,16 +798,11 @@ static int xiic_i2c_probe(struct platform_device *pdev)
|
||||
|
||||
mutex_init(&i2c->lock);
|
||||
|
||||
i2c->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL);
|
||||
if (IS_ERR(i2c->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk),
|
||||
"input clock not found.\n");
|
||||
"failed to enable input clock.\n");
|
||||
|
||||
ret = clk_prepare_enable(i2c->clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Unable to enable clock.\n");
|
||||
return ret;
|
||||
}
|
||||
i2c->dev = &pdev->dev;
|
||||
pm_runtime_set_autosuspend_delay(i2c->dev, XIIC_PM_TIMEOUT);
|
||||
pm_runtime_use_autosuspend(i2c->dev);
|
||||
@@ -820,7 +814,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Cannot claim IRQ\n");
|
||||
goto err_clk_dis;
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
i2c->singlemaster =
|
||||
@@ -841,14 +835,14 @@ static int xiic_i2c_probe(struct platform_device *pdev)
|
||||
ret = xiic_reinit(i2c);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Cannot xiic_reinit\n");
|
||||
goto err_clk_dis;
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
/* add i2c adapter to i2c tree */
|
||||
ret = i2c_add_adapter(&i2c->adap);
|
||||
if (ret) {
|
||||
xiic_deinit(i2c);
|
||||
goto err_clk_dis;
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
if (pdata) {
|
||||
@@ -859,10 +853,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_dis:
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
err_pm_disable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -880,7 +874,6 @@ static int xiic_i2c_remove(struct platform_device *pdev)
|
||||
|
||||
xiic_deinit(i2c);
|
||||
pm_runtime_put_sync(i2c->dev);
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk/clk-conf.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
@@ -66,6 +67,8 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
|
||||
static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key);
|
||||
static bool is_registered;
|
||||
|
||||
static struct dentry *i2c_debugfs_root;
|
||||
|
||||
int i2c_transfer_trace_reg(void)
|
||||
{
|
||||
static_branch_inc(&i2c_trace_msg_key);
|
||||
@@ -916,6 +919,27 @@ int i2c_dev_irq_from_resources(const struct resource *resources,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize device instantiation in case it can be instantiated explicitly
|
||||
* and by auto-detection
|
||||
*/
|
||||
static int i2c_lock_addr(struct i2c_adapter *adap, unsigned short addr,
|
||||
unsigned short flags)
|
||||
{
|
||||
if (!(flags & I2C_CLIENT_TEN) &&
|
||||
test_and_set_bit(addr, adap->addrs_in_instantiation))
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_unlock_addr(struct i2c_adapter *adap, unsigned short addr,
|
||||
unsigned short flags)
|
||||
{
|
||||
if (!(flags & I2C_CLIENT_TEN))
|
||||
clear_bit(addr, adap->addrs_in_instantiation);
|
||||
}
|
||||
|
||||
/**
|
||||
* i2c_new_client_device - instantiate an i2c device
|
||||
* @adap: the adapter managing the device
|
||||
@@ -963,6 +987,10 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
|
||||
goto out_err_silent;
|
||||
}
|
||||
|
||||
status = i2c_lock_addr(adap, client->addr, client->flags);
|
||||
if (status)
|
||||
goto out_err_silent;
|
||||
|
||||
/* Check for address business */
|
||||
status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client));
|
||||
if (status)
|
||||
@@ -994,6 +1022,8 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
|
||||
dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
|
||||
client->name, dev_name(&client->dev));
|
||||
|
||||
i2c_unlock_addr(adap, client->addr, client->flags);
|
||||
|
||||
return client;
|
||||
|
||||
out_remove_swnode:
|
||||
@@ -1005,6 +1035,7 @@ out_err:
|
||||
dev_err(&adap->dev,
|
||||
"Failed to register i2c client %s at 0x%02x (%d)\n",
|
||||
client->name, client->addr, status);
|
||||
i2c_unlock_addr(adap, client->addr, client->flags);
|
||||
out_err_silent:
|
||||
if (need_put)
|
||||
put_device(&client->dev);
|
||||
@@ -1499,6 +1530,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
|
||||
goto out_list;
|
||||
}
|
||||
|
||||
adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
|
||||
|
||||
res = i2c_setup_smbus_alert(adap);
|
||||
if (res)
|
||||
goto out_reg;
|
||||
@@ -1538,6 +1571,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
|
||||
return 0;
|
||||
|
||||
out_reg:
|
||||
debugfs_remove_recursive(adap->debugfs);
|
||||
init_completion(&adap->dev_released);
|
||||
device_unregister(&adap->dev);
|
||||
wait_for_completion(&adap->dev_released);
|
||||
@@ -1739,6 +1773,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)
|
||||
|
||||
i2c_host_notify_irq_teardown(adap);
|
||||
|
||||
debugfs_remove_recursive(adap->debugfs);
|
||||
|
||||
/* wait until all references to the device are gone
|
||||
*
|
||||
* FIXME: This is old code and should ideally be replaced by an
|
||||
@@ -1967,6 +2003,8 @@ static int __init i2c_init(void)
|
||||
|
||||
is_registered = true;
|
||||
|
||||
i2c_debugfs_root = debugfs_create_dir("i2c", NULL);
|
||||
|
||||
#ifdef CONFIG_I2C_COMPAT
|
||||
i2c_adapter_compat_class = class_compat_register("i2c-adapter");
|
||||
if (!i2c_adapter_compat_class) {
|
||||
@@ -2005,6 +2043,7 @@ static void __exit i2c_exit(void)
|
||||
#ifdef CONFIG_I2C_COMPAT
|
||||
class_compat_unregister(i2c_adapter_compat_class);
|
||||
#endif
|
||||
debugfs_remove_recursive(i2c_debugfs_root);
|
||||
bus_unregister(&i2c_bus_type);
|
||||
tracepoint_synchronize_unregister();
|
||||
}
|
||||
|
||||
@@ -692,22 +692,8 @@ static int ak8975_start_read_axis(struct ak8975_data *data,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* This will be executed only for non-interrupt based waiting case */
|
||||
if (ret & data->def->ctrl_masks[ST1_DRDY]) {
|
||||
ret = i2c_smbus_read_byte_data(client,
|
||||
data->def->ctrl_regs[ST2]);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Error in reading ST2\n");
|
||||
return ret;
|
||||
}
|
||||
if (ret & (data->def->ctrl_masks[ST2_DERR] |
|
||||
data->def->ctrl_masks[ST2_HOFL])) {
|
||||
dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Return with zero if the data is ready. */
|
||||
return !data->def->ctrl_regs[ST1_DRDY];
|
||||
}
|
||||
|
||||
/* Retrieve raw flux value for one of the x, y, or z axis. */
|
||||
@@ -734,6 +720,20 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
/* Read out ST2 for release lock on measurment data. */
|
||||
ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST2]);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Error in reading ST2\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ret & (data->def->ctrl_masks[ST2_DERR] |
|
||||
data->def->ctrl_masks[ST2_HOFL])) {
|
||||
dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
pm_runtime_mark_last_busy(&data->client->dev);
|
||||
|
||||
@@ -391,10 +391,17 @@ static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off)
|
||||
struct adp5589_kpad *kpad = gpiochip_get_data(chip);
|
||||
unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
|
||||
unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
|
||||
int val;
|
||||
|
||||
return !!(adp5589_read(kpad->client,
|
||||
kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) &
|
||||
bit);
|
||||
mutex_lock(&kpad->gpio_lock);
|
||||
if (kpad->dir[bank] & bit)
|
||||
val = kpad->dat_out[bank];
|
||||
else
|
||||
val = adp5589_read(kpad->client,
|
||||
kpad->var->reg(ADP5589_GPI_STATUS_A) + bank);
|
||||
mutex_unlock(&kpad->gpio_lock);
|
||||
|
||||
return !!(val & bit);
|
||||
}
|
||||
|
||||
static void adp5589_gpio_set_value(struct gpio_chip *chip,
|
||||
@@ -936,10 +943,9 @@ static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid)
|
||||
|
||||
static void adp5589_clear_config(void *data)
|
||||
{
|
||||
struct i2c_client *client = data;
|
||||
struct adp5589_kpad *kpad = i2c_get_clientdata(client);
|
||||
struct adp5589_kpad *kpad = data;
|
||||
|
||||
adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
|
||||
adp5589_write(kpad->client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
|
||||
}
|
||||
|
||||
static int adp5589_probe(struct i2c_client *client,
|
||||
@@ -983,7 +989,7 @@ static int adp5589_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
error = devm_add_action_or_reset(&client->dev, adp5589_clear_config,
|
||||
client);
|
||||
kpad);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -1010,8 +1016,6 @@ static int adp5589_probe(struct i2c_client *client,
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
i2c_set_clientdata(client, kpad);
|
||||
|
||||
dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -978,12 +978,12 @@ static int rmi_driver_remove(struct device *dev)
|
||||
|
||||
rmi_disable_irq(rmi_dev, false);
|
||||
|
||||
irq_domain_remove(data->irqdomain);
|
||||
data->irqdomain = NULL;
|
||||
|
||||
rmi_f34_remove_sysfs(rmi_dev);
|
||||
rmi_free_function_list(rmi_dev);
|
||||
|
||||
irq_domain_remove(data->irqdomain);
|
||||
data->irqdomain = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -273,6 +273,13 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
|
||||
u32 smr;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* MSM8998 LPASS SMMU reports 13 context banks, but accessing
|
||||
* the last context bank crashes the system.
|
||||
*/
|
||||
if (of_device_is_compatible(smmu->dev->of_node, "qcom,msm8998-smmu-v2") && smmu->num_context_banks == 13)
|
||||
smmu->num_context_banks = 12;
|
||||
|
||||
/*
|
||||
* Some platforms support more than the Arm SMMU architected maximum of
|
||||
* 128 stream matching groups. For unknown reasons, the additional
|
||||
|
||||
@@ -1189,9 +1189,7 @@ static void free_iommu(struct intel_iommu *iommu)
|
||||
*/
|
||||
static inline void reclaim_free_desc(struct q_inval *qi)
|
||||
{
|
||||
while (qi->desc_status[qi->free_tail] == QI_DONE ||
|
||||
qi->desc_status[qi->free_tail] == QI_ABORT) {
|
||||
qi->desc_status[qi->free_tail] = QI_FREE;
|
||||
while (qi->desc_status[qi->free_tail] == QI_FREE && qi->free_tail != qi->free_head) {
|
||||
qi->free_tail = (qi->free_tail + 1) % QI_LENGTH;
|
||||
qi->free_cnt++;
|
||||
}
|
||||
@@ -1426,8 +1424,16 @@ restart:
|
||||
raw_spin_lock(&qi->q_lock);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
qi->desc_status[(index + i) % QI_LENGTH] = QI_DONE;
|
||||
/*
|
||||
* The reclaim code can free descriptors from multiple submissions
|
||||
* starting from the tail of the queue. When count == 0, the
|
||||
* status of the standalone wait descriptor at the tail of the queue
|
||||
* must be set to QI_FREE to allow the reclaim code to proceed.
|
||||
* It is also possible that descriptors from one of the previous
|
||||
* submissions has to be reclaimed by a subsequent submission.
|
||||
*/
|
||||
for (i = 0; i <= count; i++)
|
||||
qi->desc_status[(index + i) % QI_LENGTH] = QI_FREE;
|
||||
|
||||
reclaim_free_desc(qi);
|
||||
raw_spin_unlock_irqrestore(&qi->q_lock, flags);
|
||||
|
||||
@@ -1697,10 +1697,10 @@ static int iommu_init_domains(struct intel_iommu *iommu)
|
||||
* entry for first-level or pass-through translation modes should
|
||||
* be programmed with a domain id different from those used for
|
||||
* second-level or nested translation. We reserve a domain id for
|
||||
* this purpose.
|
||||
* this purpose. This domain id is also used for identity domain
|
||||
* in legacy mode.
|
||||
*/
|
||||
if (sm_supported(iommu))
|
||||
set_bit(FLPT_DEFAULT_DID, iommu->domain_ids);
|
||||
set_bit(FLPT_DEFAULT_DID, iommu->domain_ids);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -718,7 +718,8 @@ static int ar0521_power_off(struct device *dev)
|
||||
clk_disable_unprepare(sensor->extclk);
|
||||
|
||||
if (sensor->reset_gpio)
|
||||
gpiod_set_value(sensor->reset_gpio, 1); /* assert RESET signal */
|
||||
/* assert RESET signal */
|
||||
gpiod_set_value_cansleep(sensor->reset_gpio, 1);
|
||||
|
||||
for (i = ARRAY_SIZE(ar0521_supply_names) - 1; i >= 0; i--) {
|
||||
if (sensor->supplies[i])
|
||||
@@ -752,7 +753,7 @@ static int ar0521_power_on(struct device *dev)
|
||||
|
||||
if (sensor->reset_gpio)
|
||||
/* deassert RESET signal */
|
||||
gpiod_set_value(sensor->reset_gpio, 0);
|
||||
gpiod_set_value_cansleep(sensor->reset_gpio, 0);
|
||||
usleep_range(4500, 5000); /* min 45000 clocks */
|
||||
|
||||
for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) {
|
||||
|
||||
@@ -75,6 +75,12 @@ struct imx335_reg_list {
|
||||
const struct imx335_reg *regs;
|
||||
};
|
||||
|
||||
static const char * const imx335_supply_name[] = {
|
||||
"avdd", /* Analog (2.9V) supply */
|
||||
"ovdd", /* Digital I/O (1.8V) supply */
|
||||
"dvdd", /* Digital Core (1.2V) supply */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct imx335_mode - imx335 sensor mode structure
|
||||
* @width: Frame width
|
||||
@@ -108,6 +114,7 @@ struct imx335_mode {
|
||||
* @sd: V4L2 sub-device
|
||||
* @pad: Media pad. Only one pad supported
|
||||
* @reset_gpio: Sensor reset gpio
|
||||
* @supplies: Regulator supplies to handle power control
|
||||
* @inclk: Sensor input clock
|
||||
* @ctrl_handler: V4L2 control handler
|
||||
* @link_freq_ctrl: Pointer to link frequency control
|
||||
@@ -127,6 +134,8 @@ struct imx335 {
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct regulator_bulk_data supplies[ARRAY_SIZE(imx335_supply_name)];
|
||||
|
||||
struct clk *inclk;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
struct v4l2_ctrl *link_freq_ctrl;
|
||||
@@ -783,13 +792,24 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
|
||||
|
||||
/* Request optional reset pin */
|
||||
imx335->reset_gpio = devm_gpiod_get_optional(imx335->dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(imx335->reset_gpio)) {
|
||||
dev_err(imx335->dev, "failed to get reset gpio %ld",
|
||||
PTR_ERR(imx335->reset_gpio));
|
||||
return PTR_ERR(imx335->reset_gpio);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(imx335_supply_name); i++)
|
||||
imx335->supplies[i].supply = imx335_supply_name[i];
|
||||
|
||||
ret = devm_regulator_bulk_get(imx335->dev,
|
||||
ARRAY_SIZE(imx335_supply_name),
|
||||
imx335->supplies);
|
||||
if (ret) {
|
||||
dev_err(imx335->dev, "Failed to get regulators\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get sensor input clock */
|
||||
imx335->inclk = devm_clk_get(imx335->dev, NULL);
|
||||
if (IS_ERR(imx335->inclk)) {
|
||||
@@ -868,7 +888,17 @@ static int imx335_power_on(struct device *dev)
|
||||
struct imx335 *imx335 = to_imx335(sd);
|
||||
int ret;
|
||||
|
||||
gpiod_set_value_cansleep(imx335->reset_gpio, 1);
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(imx335_supply_name),
|
||||
imx335->supplies);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: failed to enable regulators\n",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
usleep_range(500, 550); /* Tlow */
|
||||
|
||||
gpiod_set_value_cansleep(imx335->reset_gpio, 0);
|
||||
|
||||
ret = clk_prepare_enable(imx335->inclk);
|
||||
if (ret) {
|
||||
@@ -876,12 +906,13 @@ static int imx335_power_on(struct device *dev)
|
||||
goto error_reset;
|
||||
}
|
||||
|
||||
usleep_range(20, 22);
|
||||
usleep_range(20, 22); /* T4 */
|
||||
|
||||
return 0;
|
||||
|
||||
error_reset:
|
||||
gpiod_set_value_cansleep(imx335->reset_gpio, 0);
|
||||
gpiod_set_value_cansleep(imx335->reset_gpio, 1);
|
||||
regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -897,9 +928,9 @@ static int imx335_power_off(struct device *dev)
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct imx335 *imx335 = to_imx335(sd);
|
||||
|
||||
gpiod_set_value_cansleep(imx335->reset_gpio, 0);
|
||||
|
||||
gpiod_set_value_cansleep(imx335->reset_gpio, 1);
|
||||
clk_disable_unprepare(imx335->inclk);
|
||||
regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1663,6 +1663,8 @@ static int camss_probe(struct platform_device *pdev)
|
||||
|
||||
v4l2_async_nf_init(&camss->notifier);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
num_subdevs = camss_of_parse_ports(camss);
|
||||
if (num_subdevs < 0) {
|
||||
ret = num_subdevs;
|
||||
@@ -1700,8 +1702,6 @@ static int camss_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_register_subdevs:
|
||||
@@ -1709,6 +1709,7 @@ err_register_subdevs:
|
||||
err_v4l2_device_unregister:
|
||||
v4l2_device_unregister(&camss->v4l2_dev);
|
||||
v4l2_async_nf_cleanup(&camss->notifier);
|
||||
pm_runtime_disable(dev);
|
||||
err_genpd_cleanup:
|
||||
camss_genpd_cleanup(camss);
|
||||
|
||||
|
||||
@@ -423,6 +423,7 @@ static int venus_remove(struct platform_device *pdev)
|
||||
struct device *dev = core->dev;
|
||||
int ret;
|
||||
|
||||
cancel_delayed_work_sync(&core->work);
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
WARN_ON(ret < 0);
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ static const struct media_entity_operations sun4i_csi_video_entity_ops = {
|
||||
.link_validate = v4l2_subdev_link_validate,
|
||||
};
|
||||
|
||||
static const struct media_entity_operations sun4i_csi_subdev_entity_ops = {
|
||||
.link_validate = v4l2_subdev_link_validate,
|
||||
};
|
||||
|
||||
static int sun4i_csi_notify_bound(struct v4l2_async_notifier *notifier,
|
||||
struct v4l2_subdev *subdev,
|
||||
struct v4l2_async_subdev *asd)
|
||||
@@ -214,6 +218,7 @@ static int sun4i_csi_probe(struct platform_device *pdev)
|
||||
v4l2_subdev_init(subdev, &sun4i_csi_subdev_ops);
|
||||
subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||
subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
|
||||
subdev->entity.ops = &sun4i_csi_subdev_entity_ops;
|
||||
subdev->owner = THIS_MODULE;
|
||||
snprintf(subdev->name, sizeof(subdev->name), "sun4i-csi-0");
|
||||
v4l2_set_subdevdata(subdev, csi);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user