Merge remote-tracking branch 'auto-kernel-ci' into auto-kernel

* auto-kernel-ci:
  goodix_driver_gt9886: cleanup and fix code styling
  ARM64: configs: raphael: Enable GAMEMODE support
  goodix_driver_gt9886: Implement GAMEMODE Support
  ARM64: configs: raphael: Balance schedutil up/down rate limits
  cpufreq: schedutil: Apply init protection to default configuration options
  cpufreq: schedutil: Enable iowait boost by default
  sched: features: Disable EAS_PREFER_IDLE
  [TEMP]: Kbuild: disable compound-token-split-by-space warnings
  Makefile: Enable LLVM integrated assembler also for assembly files
  crypto: arm64/aes-modes - get rid of literal load of addend vector
  crypto: arm64/chacha20 - move kernel mode neon en/disable into loop
  crypto: arm64/aes-bs - move kernel mode neon en/disable into loop
  crypto: arm64/aes-blk - move kernel mode neon en/disable into loop
  crypto: arm64/aes-ce-ccm - move kernel mode neon en/disable into loop
  kbuild: use LLVM integrated assembler for C files
  drm: msm: sde: Cleanup and optimize sde_connector_update_hbm
  drm: msm: sde: Remove mutex usage in sde_connector_update_hbm
  drm: msm: Fix dimlayer when dc is enabled
  drm: msm: Add support to block fod dimlayer backlight
  drm: msm: dsi_panel: Add support to skip set backlight
  drm: msm: cleanup xiaomi changes for sanity
  Revert "drm: msm: sde: workaround for miui like fod behaviour"
  drone: switch to Full LTO builds
  drone: update for new scripts
  README: Refactor and update
  ARM64: configs: raphael: Enable stack & heap initialization
  scripts: dtc: Enable avoid_unnecessary_addr_size warnings
  Linux 4.14.196
  ALSA: usb-audio: Update documentation comment for MS2109 quirk
  HID: hiddev: Fix slab-out-of-bounds write in hiddev_ioctl_usage()
  tpm: Unify the mismatching TPM space buffer sizes
  btrfs: check the right error variable in btrfs_del_dir_entries_in_log
  usb: storage: Add unusual_uas entry for Sony PSZ drives
  USB: cdc-acm: rework notification_buffer resizing
  USB: gadget: u_f: Unbreak offset calculation in VLAs
  USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb()
  USB: gadget: u_f: add overflow checks to VLA macros
  overflow.h: Add allocation size calculation helpers
  usb: host: ohci-exynos: Fix error handling in exynos_ohci_probe()
  USB: Ignore UAS for JMicron JMS567 ATA/ATAPI Bridge
  USB: quirks: Add no-lpm quirk for another Raydium touchscreen
  usb: uas: Add quirk for PNY Pro Elite
  USB: yurex: Fix bad gfp argument
  drm/amdgpu: Fix buffer overflow in INFO ioctl
  device property: Fix the secondary firmware node handling in set_primary_fwnode()
  PM: sleep: core: Fix the handling of pending runtime resume requests
  xhci: Do warm-reset when both CAS and XDEV_RESUME are set
  XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt XEN data pointer which contains XEN specific information.
  writeback: Fix sync livelock due to b_dirty_time processing
  writeback: Avoid skipping inode writeback
  writeback: Protect inode->i_io_list with inode->i_lock
  serial: 8250: change lock order in serial8250_do_startup()
  serial: 8250_exar: Fix number of ports for Commtech PCIe cards
  serial: pl011: Don't leak amba_ports entry on driver register error
  serial: pl011: Fix oops on -EPROBE_DEFER
  serial: samsung: Removes the IRQ not found warning
  vt_ioctl: change VT_RESIZEX ioctl to check for error return from vc_resize()
  vt: defer kfree() of vc_screenbuf in vc_do_resize()
  USB: lvtest: return proper error code in probe
  fbcon: prevent user font height or width change from causing potential out-of-bounds access
  btrfs: fix space cache memory leak after transaction abort
  HID: i2c-hid: Always sleep 60ms after I2C_HID_PWR_ON commands
  powerpc/perf: Fix soft lockups due to missed interrupt accounting
  net: gianfar: Add of_node_put() before goto statement
  scsi: ufs: Clean up completed request without interrupt notification
  scsi: ufs: Improve interrupt handling for shared interrupts
  scsi: ufs: Fix possible infinite loop in ufshcd_hold
  s390/cio: add cond_resched() in the slow_eval_known_fn() loop
  spi: stm32: fix stm32_spi_prepare_mbr in case of odd clk_rate
  fs: prevent BUG_ON in submit_bh_wbc()
  jbd2: abort journal if free a async write error metadata buffer
  ext4: don't BUG on inconsistent journal feature
  jbd2: make sure jh have b_transaction set in refile/unfile_buffer
  usb: gadget: f_tcm: Fix some resource leaks in some error paths
  i2c: rcar: in slave mode, clear NACK earlier
  null_blk: fix passing of REQ_FUA flag in null_handle_rq
  nvme-fc: Fix wrong return value in __nvme_fc_init_request()
  media: gpio-ir-tx: improve precision of transmitted signal due to scheduling
  Revert "ath10k: fix DMA related firmware crashes on multiple devices"
  efi: provide empty efi_enter_virtual_mode implementation
  USB: sisusbvga: Fix a potential UB casued by left shifting a negative value
  powerpc/spufs: add CONFIG_COREDUMP dependency
  KVM: arm64: Fix symbol dependency in __hyp_call_panic_nvhe
  media: davinci: vpif_capture: fix potential double free
  EDAC/ie31200: Fallback if host bridge device is already initialized
  scsi: fcoe: Memory leak fix in fcoe_sysfs_fcf_del()
  ceph: fix potential mdsc use-after-free crash
  scsi: iscsi: Do not put host in iscsi_set_flashnode_param()
  locking/lockdep: Fix overflow in presentation of average lock-time
  drm/nouveau: Fix reference count leak in nouveau_connector_detect
  drm/nouveau/drm/noveau: fix reference count leak in nouveau_fbcon_open
  f2fs: fix use-after-free issue
  cec-api: prevent leaking memory through hole in structure
  mips/vdso: Fix resource leaks in genvdso.c
  rtlwifi: rtl8192cu: Prevent leaking urb
  PCI: Fix pci_create_slot() reference count leak
  omapfb: fix multiple reference count leaks due to pm_runtime_get_sync
  selftests/powerpc: Purge extra count_pmc() calls of ebb selftests
  scsi: lpfc: Fix shost refcount mismatch when deleting vport
  drm/amdgpu/display: fix ref count leak when pm_runtime_get_sync fails
  drm/amdgpu: fix ref count leak in amdgpu_display_crtc_set_config
  drm/amd/display: fix ref count leak in amdgpu_drm_ioctl
  drm/amdgpu: fix ref count leak in amdgpu_driver_open_kms
  drm/radeon: fix multiple reference count leak
  drm/amdkfd: Fix reference count leaks.
  iommu/iova: Don't BUG on invalid PFNs
  scsi: target: tcmu: Fix crash on ARM during cmd completion
  blktrace: ensure our debugfs dir exists
  media: pci: ttpci: av7110: fix possible buffer overflow caused by bad DMA value in debiirq()
  powerpc/xive: Ignore kmemleak false positives
  arm64: dts: qcom: msm8916: Pull down PDM GPIOs during sleep
  mfd: intel-lpss: Add Intel Emmitsburg PCH PCI IDs
  ASoC: tegra: Fix reference count leaks.
  ALSA: pci: delete repeated words in comments
  gre6: Fix reception with IP6_TNL_F_RCV_DSCP_COPY
  ipvlan: fix device features
  tipc: fix uninit skb->data in tipc_nl_compat_dumpit()
  net: Fix potential wrong skb->protocol in skb_vlan_untag()
  powerpc/64s: Don't init FSCR_DSCR in __init_FSCR()
  ANDROID: cuttlefish_defconfig: initialize locals with zeroes
  BACKPORT: security: allow using Clang's zero initialization for stack variables
  Revert "binder: Prevent context manager from incrementing ref 0"

Signed-off-by: UtsavBalar1231 <utsavbalar1231@gmail.com>
This commit is contained in:
UtsavBalar1231
2020-09-08 14:04:33 +05:30
137 changed files with 1527 additions and 1102 deletions

View File

@@ -18,12 +18,14 @@ steps:
from_secret: ci_channel_id
BOT_API_KEY:
from_secret: bot_api_key
RELEASE_VERSION: "test"
TYPE: "LOSFOD"
commands:
- apt-get update && apt-get install -y bison build-essential bc bison curl libssl-dev git zip python flex
- git clone --depth=1 https://github.com/UtsavBalar1231/scripts.git -b master script && cd script
- ./dronesetup.sh --proton
- ./kernel.sh --proton
- git clone https://github.com/UtsavBalar1231/Drone-scripts.git -b master script && cd script
- ./setup-drone --proton
- ./build-kernel --proton --lto
when:
branch:
- auto-kernel-ci
- auto-kernel
event:
- push

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 14
SUBLEVEL = 195
SUBLEVEL = 196
EXTRAVERSION =
NAME = Petit Gorille
@@ -515,7 +515,6 @@ endif
ifneq ($(GCC_TOOLCHAIN),)
CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN)
endif
CLANG_FLAGS += -no-integrated-as
CLANG_FLAGS += -Werror=unknown-warning-option
CLANG_FLAGS += $(call cc-option, -Wno-misleading-indentation)
CLANG_FLAGS += $(call cc-option, -Wno-bool-operation)
@@ -793,6 +792,7 @@ ifeq ($(cc-name),clang)
KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
KBUILD_CFLAGS += $(call cc-disable-warning, duplicate-decl-specifier)
KBUILD_CFLAGS += $(call cc-disable-warning, compound-token-split-by-space)
KBUILD_CFLAGS += $(call cc-option, -Wno-undefined-optimized)
KBUILD_CFLAGS += $(call cc-option, -Wno-tautological-constant-out-of-range-compare)
KBUILD_CFLAGS += $(call cc-option, -mllvm -disable-struct-const-merge)
@@ -839,12 +839,20 @@ ifndef CONFIG_FUNCTION_TRACER
KBUILD_CFLAGS += -fomit-frame-pointer
endif
endif
# Initialize all stack variables with a pattern, if desired.
ifdef CONFIG_INIT_STACK_ALL
# Initialize all stack variables with a 0xAA pattern.
ifdef CONFIG_INIT_STACK_ALL_PATTERN
KBUILD_CFLAGS += -ftrivial-auto-var-init=pattern
endif
# Initialize all stack variables with a zero value.
ifdef CONFIG_INIT_STACK_ALL_ZERO
# Future support for zero initialization is still being debated, see
# https://bugs.llvm.org/show_bug.cgi?id=45497. These flags are subject to being
# renamed or dropped.
KBUILD_CFLAGS += -ftrivial-auto-var-init=zero
KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
endif
KBUILD_CFLAGS += $(call cc-option, -fno-var-tracking-assignments)
ifdef CONFIG_DEBUG_INFO

View File

@@ -1,8 +1,19 @@
# IMMENSiTY KERNAL for Redmi K20pro / Mi9Tpro
## IMMENSiTY KERNEL
## For Redmi K20 Pro and Mi9T Pro
[![Build Status](https://cloud.drone.io/api/badges/UtsavBalar1231/kernel_xiaomi_raphael/status.svg?ref=refs/heads/auto-kernel-ci)](https://cloud.drone.io/UtsavBalar1231/kernel_xiaomi_raphael)
![logo](https://github.com/UtsavBalar1231/xda-stuff/raw/master/immensity-new.png "logo here")
![CommitCount](https://img.shields.io/github/commits-since/utsavbalar1231/kernel_xiaomi_raphael/0.9.0/auto-kernel)
[![HitCount](http://hits.dwyl.com/UtsavBalar1231/kernel_xiaomi_raphael.svg)](http://hits.dwyl.com/UtsavBalar1231/kernel_xiaomi_raphael)
![logo](https://github.com/UtsavBalar1231/xda-stuff/raw/master/immensity-pinkcity.png "bruh logo is here")
> Merged AOSP android-4.14-stable [4.14.195]
> Latest CAF tag: **LE.UM.3.2.3-00110-SA2150p**
## Base
> android-4.14-stable **4.14.196**
>
> CAF **LE.UM.3.2.3-00110-SA2150p**
## Technical Information
![poggers](https://github.com/UtsavBalar1231/xda-stuff/raw/master/immensity-greenlight.png "bruh design is here")
> XDA Thread [HERE](https://forum.xda-developers.com/k20-pro/development/kernel-immensity-kernel-t3962389)
>
> Telegram Group [HERE](https://t.me/cuntsspace)
>
> C.I Channel [HERE](https://t.me/cuntsreleases)

View File

@@ -555,7 +555,7 @@
pins = "gpio63", "gpio64", "gpio65", "gpio66",
"gpio67", "gpio68";
drive-strength = <2>;
bias-disable;
bias-pull-down;
};
};
};

View File

@@ -473,7 +473,7 @@ CONFIG_LSM_MMAP_MIN_ADDR=65536
CONFIG_HARDENED_USERCOPY=y
CONFIG_STATIC_USERMODEHELPER=y
CONFIG_SECURITY_SELINUX=y
CONFIG_INIT_STACK_ALL=y
CONFIG_INIT_STACK_ALL_ZERO=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_CRYPTO_ADIANTUM=y
CONFIG_CRYPTO_LZ4=y

View File

@@ -741,8 +741,8 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
# CONFIG_CPU_BOOST is not set
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_SCHEDUTIL_UP_RATE_LIMIT=0
CONFIG_SCHEDUTIL_DOWN_RATE_LIMIT=0
CONFIG_SCHEDUTIL_UP_RATE_LIMIT=5000
CONFIG_SCHEDUTIL_DOWN_RATE_LIMIT=10000
# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set
CONFIG_CPU_FREQ_DEFAULT_LITTLE_MIN=1036800
CONFIG_CPU_FREQ_DEFAULT_BIG_MIN=1056000
@@ -1892,6 +1892,7 @@ CONFIG_TOUCHSCREEN_GOODIX_GTX8=y
CONFIG_TOUCHSCREEN_GOODIX_GTX8_UPDATE=y
CONFIG_TOUCHSCREEN_GOODIX_GTX8_GESTURE=y
# CONFIG_TOUCHSCREEN_GOODIX_GTX8_TOOLS is not set
CONFIG_TOUCHSCREEN_GOODIX_GTX8_GAMEMODE=y
CONFIG_TOUCHSCREEN_PROPERTIES=y
# CONFIG_TOUCHSCREEN_ADS7846 is not set
# CONFIG_TOUCHSCREEN_AD7877 is not set
@@ -5130,9 +5131,10 @@ CONFIG_DEFAULT_SECURITY="selinux"
#
# Memory initialization
#
CONFIG_INIT_STACK_NONE=y
# CONFIG_INIT_STACK_ALL is not set
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
# CONFIG_INIT_STACK_NONE is not set
# CONFIG_INIT_STACK_ALL_PATTERN is not set
CONFIG_INIT_STACK_ALL_ZERO=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
CONFIG_CRYPTO=y

View File

@@ -107,11 +107,13 @@ static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
}
static void ccm_update_mac(struct crypto_aes_ctx *key, u8 mac[], u8 const in[],
u32 abytes, u32 *macp, bool use_neon)
u32 abytes, u32 *macp)
{
if (likely(use_neon)) {
if (may_use_simd()) {
kernel_neon_begin();
ce_aes_ccm_auth_data(mac, in, abytes, macp, key->key_enc,
num_rounds(key));
kernel_neon_end();
} else {
if (*macp > 0 && *macp < AES_BLOCK_SIZE) {
int added = min(abytes, AES_BLOCK_SIZE - *macp);
@@ -141,8 +143,7 @@ static void ccm_update_mac(struct crypto_aes_ctx *key, u8 mac[], u8 const in[],
}
}
static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[],
bool use_neon)
static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
{
struct crypto_aead *aead = crypto_aead_reqtfm(req);
struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
@@ -161,7 +162,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[],
ltag.len = 6;
}
ccm_update_mac(ctx, mac, (u8 *)&ltag, ltag.len, &macp, use_neon);
ccm_update_mac(ctx, mac, (u8 *)&ltag, ltag.len, &macp);
scatterwalk_start(&walk, req->src);
do {
@@ -173,7 +174,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[],
n = scatterwalk_clamp(&walk, len);
}
p = scatterwalk_map(&walk);
ccm_update_mac(ctx, mac, p, n, &macp, use_neon);
ccm_update_mac(ctx, mac, p, n, &macp);
len -= n;
scatterwalk_unmap(p);
@@ -240,43 +241,42 @@ static int ccm_encrypt(struct aead_request *req)
u8 __aligned(8) mac[AES_BLOCK_SIZE];
u8 buf[AES_BLOCK_SIZE];
u32 len = req->cryptlen;
bool use_neon = may_use_simd();
int err;
err = ccm_init_mac(req, mac, len);
if (err)
return err;
if (likely(use_neon))
kernel_neon_begin();
if (req->assoclen)
ccm_calculate_auth_mac(req, mac, use_neon);
ccm_calculate_auth_mac(req, mac);
/* preserve the original iv for the final round */
memcpy(buf, req->iv, AES_BLOCK_SIZE);
err = skcipher_walk_aead_encrypt(&walk, req, true);
if (likely(use_neon)) {
if (may_use_simd()) {
while (walk.nbytes) {
u32 tail = walk.nbytes % AES_BLOCK_SIZE;
if (walk.nbytes == walk.total)
tail = 0;
kernel_neon_begin();
ce_aes_ccm_encrypt(walk.dst.virt.addr,
walk.src.virt.addr,
walk.nbytes - tail, ctx->key_enc,
num_rounds(ctx), mac, walk.iv);
kernel_neon_end();
err = skcipher_walk_done(&walk, tail);
}
if (!err)
if (!err) {
kernel_neon_begin();
ce_aes_ccm_final(mac, buf, ctx->key_enc,
num_rounds(ctx));
kernel_neon_end();
kernel_neon_end();
}
} else {
err = ccm_crypt_fallback(&walk, mac, buf, ctx, true);
}
@@ -299,43 +299,42 @@ static int ccm_decrypt(struct aead_request *req)
u8 __aligned(8) mac[AES_BLOCK_SIZE];
u8 buf[AES_BLOCK_SIZE];
u32 len = req->cryptlen - authsize;
bool use_neon = may_use_simd();
int err;
err = ccm_init_mac(req, mac, len);
if (err)
return err;
if (likely(use_neon))
kernel_neon_begin();
if (req->assoclen)
ccm_calculate_auth_mac(req, mac, use_neon);
ccm_calculate_auth_mac(req, mac);
/* preserve the original iv for the final round */
memcpy(buf, req->iv, AES_BLOCK_SIZE);
err = skcipher_walk_aead_decrypt(&walk, req, true);
if (likely(use_neon)) {
if (may_use_simd()) {
while (walk.nbytes) {
u32 tail = walk.nbytes % AES_BLOCK_SIZE;
if (walk.nbytes == walk.total)
tail = 0;
kernel_neon_begin();
ce_aes_ccm_decrypt(walk.dst.virt.addr,
walk.src.virt.addr,
walk.nbytes - tail, ctx->key_enc,
num_rounds(ctx), mac, walk.iv);
kernel_neon_end();
err = skcipher_walk_done(&walk, tail);
}
if (!err)
if (!err) {
kernel_neon_begin();
ce_aes_ccm_final(mac, buf, ctx->key_enc,
num_rounds(ctx));
kernel_neon_end();
kernel_neon_end();
}
} else {
err = ccm_crypt_fallback(&walk, mac, buf, ctx, false);
}

View File

@@ -64,17 +64,17 @@ MODULE_LICENSE("GPL v2");
/* defined in aes-modes.S */
asmlinkage void aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, int first);
int rounds, int blocks);
asmlinkage void aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, int first);
int rounds, int blocks);
asmlinkage void aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 iv[], int first);
int rounds, int blocks, u8 iv[]);
asmlinkage void aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 iv[], int first);
int rounds, int blocks, u8 iv[]);
asmlinkage void aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
int rounds, int blocks, u8 ctr[], int first);
int rounds, int blocks, u8 ctr[]);
asmlinkage void aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[],
int rounds, int blocks, u8 const rk2[], u8 iv[],
@@ -133,19 +133,19 @@ static int ecb_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
int err, first, rounds = 6 + ctx->key_length / 4;
int err, rounds = 6 + ctx->key_length / 4;
struct skcipher_walk walk;
unsigned int blocks;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
kernel_neon_begin();
aes_ecb_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
(u8 *)ctx->key_enc, rounds, blocks, first);
(u8 *)ctx->key_enc, rounds, blocks);
kernel_neon_end();
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -153,19 +153,19 @@ static int ecb_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
int err, first, rounds = 6 + ctx->key_length / 4;
int err, rounds = 6 + ctx->key_length / 4;
struct skcipher_walk walk;
unsigned int blocks;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
kernel_neon_begin();
aes_ecb_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
(u8 *)ctx->key_dec, rounds, blocks, first);
(u8 *)ctx->key_dec, rounds, blocks);
kernel_neon_end();
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -173,20 +173,19 @@ static int cbc_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
int err, first, rounds = 6 + ctx->key_length / 4;
int err, rounds = 6 + ctx->key_length / 4;
struct skcipher_walk walk;
unsigned int blocks;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
kernel_neon_begin();
aes_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
(u8 *)ctx->key_enc, rounds, blocks, walk.iv,
first);
(u8 *)ctx->key_enc, rounds, blocks, walk.iv);
kernel_neon_end();
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -194,20 +193,19 @@ static int cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
int err, first, rounds = 6 + ctx->key_length / 4;
int err, rounds = 6 + ctx->key_length / 4;
struct skcipher_walk walk;
unsigned int blocks;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
kernel_neon_begin();
aes_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
(u8 *)ctx->key_dec, rounds, blocks, walk.iv,
first);
(u8 *)ctx->key_dec, rounds, blocks, walk.iv);
kernel_neon_end();
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -215,20 +213,18 @@ static int ctr_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
int err, first, rounds = 6 + ctx->key_length / 4;
int err, rounds = 6 + ctx->key_length / 4;
struct skcipher_walk walk;
int blocks;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
first = 1;
kernel_neon_begin();
while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
kernel_neon_begin();
aes_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
(u8 *)ctx->key_enc, rounds, blocks, walk.iv,
first);
(u8 *)ctx->key_enc, rounds, blocks, walk.iv);
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
first = 0;
kernel_neon_end();
}
if (walk.nbytes) {
u8 __aligned(8) tail[AES_BLOCK_SIZE];
@@ -241,12 +237,13 @@ static int ctr_encrypt(struct skcipher_request *req)
*/
blocks = -1;
kernel_neon_begin();
aes_ctr_encrypt(tail, NULL, (u8 *)ctx->key_enc, rounds,
blocks, walk.iv, first);
blocks, walk.iv);
kernel_neon_end();
crypto_xor_cpy(tdst, tsrc, tail, nbytes);
err = skcipher_walk_done(&walk, 0);
}
kernel_neon_end();
return err;
}
@@ -270,16 +267,16 @@ static int xts_encrypt(struct skcipher_request *req)
struct skcipher_walk walk;
unsigned int blocks;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
kernel_neon_begin();
aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
(u8 *)ctx->key1.key_enc, rounds, blocks,
(u8 *)ctx->key2.key_enc, walk.iv, first);
kernel_neon_end();
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -292,16 +289,16 @@ static int xts_decrypt(struct skcipher_request *req)
struct skcipher_walk walk;
unsigned int blocks;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
kernel_neon_begin();
aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
(u8 *)ctx->key1.key_dec, rounds, blocks,
(u8 *)ctx->key2.key_enc, walk.iv, first);
kernel_neon_end();
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -425,7 +422,7 @@ static int cmac_setkey(struct crypto_shash *tfm, const u8 *in_key,
/* encrypt the zero vector */
kernel_neon_begin();
aes_ecb_encrypt(ctx->consts, (u8[AES_BLOCK_SIZE]){}, rk, rounds, 1, 1);
aes_ecb_encrypt(ctx->consts, (u8[AES_BLOCK_SIZE]){}, rk, rounds, 1);
kernel_neon_end();
cmac_gf128_mul_by_x(consts, consts);
@@ -454,8 +451,8 @@ static int xcbc_setkey(struct crypto_shash *tfm, const u8 *in_key,
return err;
kernel_neon_begin();
aes_ecb_encrypt(key, ks[0], rk, rounds, 1, 1);
aes_ecb_encrypt(ctx->consts, ks[1], rk, rounds, 2, 0);
aes_ecb_encrypt(key, ks[0], rk, rounds, 1);
aes_ecb_encrypt(ctx->consts, ks[1], rk, rounds, 2);
kernel_neon_end();
return cbcmac_setkey(tfm, key, sizeof(key));

View File

@@ -40,24 +40,24 @@
#if INTERLEAVE == 2
aes_encrypt_block2x:
encrypt_block2x v0, v1, w3, x2, x6, w7
encrypt_block2x v0, v1, w3, x2, x8, w7
ret
ENDPROC(aes_encrypt_block2x)
aes_decrypt_block2x:
decrypt_block2x v0, v1, w3, x2, x6, w7
decrypt_block2x v0, v1, w3, x2, x8, w7
ret
ENDPROC(aes_decrypt_block2x)
#elif INTERLEAVE == 4
aes_encrypt_block4x:
encrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
encrypt_block4x v0, v1, v2, v3, w3, x2, x8, w7
ret
ENDPROC(aes_encrypt_block4x)
aes_decrypt_block4x:
decrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
decrypt_block4x v0, v1, v2, v3, w3, x2, x8, w7
ret
ENDPROC(aes_decrypt_block4x)
@@ -86,33 +86,32 @@ ENDPROC(aes_decrypt_block4x)
#define FRAME_POP
.macro do_encrypt_block2x
encrypt_block2x v0, v1, w3, x2, x6, w7
encrypt_block2x v0, v1, w3, x2, x8, w7
.endm
.macro do_decrypt_block2x
decrypt_block2x v0, v1, w3, x2, x6, w7
decrypt_block2x v0, v1, w3, x2, x8, w7
.endm
.macro do_encrypt_block4x
encrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
encrypt_block4x v0, v1, v2, v3, w3, x2, x8, w7
.endm
.macro do_decrypt_block4x
decrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
decrypt_block4x v0, v1, v2, v3, w3, x2, x8, w7
.endm
#endif
/*
* aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
* int blocks, int first)
* int blocks)
* aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
* int blocks, int first)
* int blocks)
*/
AES_ENTRY(aes_ecb_encrypt)
FRAME_PUSH
cbz w5, .LecbencloopNx
enc_prepare w3, x2, x5
@@ -148,7 +147,6 @@ AES_ENDPROC(aes_ecb_encrypt)
AES_ENTRY(aes_ecb_decrypt)
FRAME_PUSH
cbz w5, .LecbdecloopNx
dec_prepare w3, x2, x5
@@ -184,14 +182,12 @@ AES_ENDPROC(aes_ecb_decrypt)
/*
* aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
* int blocks, u8 iv[], int first)
* int blocks, u8 iv[])
* aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
* int blocks, u8 iv[], int first)
* int blocks, u8 iv[])
*/
AES_ENTRY(aes_cbc_encrypt)
cbz w6, .Lcbcencloop
ld1 {v0.16b}, [x5] /* get iv */
enc_prepare w3, x2, x6
@@ -209,7 +205,6 @@ AES_ENDPROC(aes_cbc_encrypt)
AES_ENTRY(aes_cbc_decrypt)
FRAME_PUSH
cbz w6, .LcbcdecloopNx
ld1 {v7.16b}, [x5] /* get iv */
dec_prepare w3, x2, x6
@@ -264,20 +259,19 @@ AES_ENDPROC(aes_cbc_decrypt)
/*
* aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
* int blocks, u8 ctr[], int first)
* int blocks, u8 ctr[])
*/
AES_ENTRY(aes_ctr_encrypt)
FRAME_PUSH
cbz w6, .Lctrnotfirst /* 1st time around? */
enc_prepare w3, x2, x6
ld1 {v4.16b}, [x5]
.Lctrnotfirst:
umov x8, v4.d[1] /* keep swabbed ctr in reg */
rev x8, x8
umov x6, v4.d[1] /* keep swabbed ctr in reg */
rev x6, x6
#if INTERLEAVE >= 2
cmn w8, w4 /* 32 bit overflow? */
cmn w6, w4 /* 32 bit overflow? */
bcs .Lctrloop
.LctrloopNx:
subs w4, w4, #INTERLEAVE
@@ -285,11 +279,11 @@ AES_ENTRY(aes_ctr_encrypt)
#if INTERLEAVE == 2
mov v0.8b, v4.8b
mov v1.8b, v4.8b
rev x7, x8
add x8, x8, #1
rev x7, x6
add x6, x6, #1
ins v0.d[1], x7
rev x7, x8
add x8, x8, #1
rev x7, x6
add x6, x6, #1
ins v1.d[1], x7
ld1 {v2.16b-v3.16b}, [x1], #32 /* get 2 input blocks */
do_encrypt_block2x
@@ -297,17 +291,19 @@ AES_ENTRY(aes_ctr_encrypt)
eor v1.16b, v1.16b, v3.16b
st1 {v0.16b-v1.16b}, [x0], #32
#else
ldr q8, =0x30000000200000001 /* addends 1,2,3[,0] */
dup v7.4s, w8
add w7, w6, #1
mov v0.16b, v4.16b
add v7.4s, v7.4s, v8.4s
add w8, w6, #2
mov v1.16b, v4.16b
rev32 v8.16b, v7.16b
add w9, w6, #3
mov v2.16b, v4.16b
rev w7, w7
mov v3.16b, v4.16b
mov v1.s[3], v8.s[0]
mov v2.s[3], v8.s[1]
mov v3.s[3], v8.s[2]
rev w8, w8
mov v1.s[3], w7
rev w9, w9
mov v2.s[3], w8
mov v3.s[3], w9
ld1 {v5.16b-v7.16b}, [x1], #48 /* get 3 input blocks */
do_encrypt_block4x
eor v0.16b, v5.16b, v0.16b
@@ -316,9 +312,9 @@ AES_ENTRY(aes_ctr_encrypt)
eor v2.16b, v7.16b, v2.16b
eor v3.16b, v5.16b, v3.16b
st1 {v0.16b-v3.16b}, [x0], #64
add x8, x8, #INTERLEAVE
add x6, x6, #INTERLEAVE
#endif
rev x7, x8
rev x7, x6
ins v4.d[1], x7
cbz w4, .Lctrout
b .LctrloopNx
@@ -328,10 +324,10 @@ AES_ENTRY(aes_ctr_encrypt)
#endif
.Lctrloop:
mov v0.16b, v4.16b
encrypt_block v0, w3, x2, x6, w7
encrypt_block v0, w3, x2, x8, w7
adds x8, x8, #1 /* increment BE ctr */
rev x7, x8
adds x6, x6, #1 /* increment BE ctr */
rev x7, x6
ins v4.d[1], x7
bcs .Lctrcarry /* overflow? */
@@ -385,15 +381,17 @@ CPU_BE( .quad 0x87, 1 )
AES_ENTRY(aes_xts_encrypt)
FRAME_PUSH
cbz w7, .LxtsencloopNx
ld1 {v4.16b}, [x6]
enc_prepare w3, x5, x6
encrypt_block v4, w3, x5, x6, w7 /* first tweak */
enc_switch_key w3, x2, x6
cbz w7, .Lxtsencnotfirst
enc_prepare w3, x5, x8
encrypt_block v4, w3, x5, x8, w7 /* first tweak */
enc_switch_key w3, x2, x8
ldr q7, .Lxts_mul_x
b .LxtsencNx
.Lxtsencnotfirst:
enc_prepare w3, x2, x8
.LxtsencloopNx:
ldr q7, .Lxts_mul_x
next_tweak v4, v4, v7, v8
@@ -442,7 +440,7 @@ AES_ENTRY(aes_xts_encrypt)
.Lxtsencloop:
ld1 {v1.16b}, [x1], #16
eor v0.16b, v1.16b, v4.16b
encrypt_block v0, w3, x2, x6, w7
encrypt_block v0, w3, x2, x8, w7
eor v0.16b, v0.16b, v4.16b
st1 {v0.16b}, [x0], #16
subs w4, w4, #1
@@ -450,6 +448,7 @@ AES_ENTRY(aes_xts_encrypt)
next_tweak v4, v4, v7, v8
b .Lxtsencloop
.Lxtsencout:
st1 {v4.16b}, [x6]
FRAME_POP
ret
AES_ENDPROC(aes_xts_encrypt)
@@ -457,15 +456,17 @@ AES_ENDPROC(aes_xts_encrypt)
AES_ENTRY(aes_xts_decrypt)
FRAME_PUSH
cbz w7, .LxtsdecloopNx
ld1 {v4.16b}, [x6]
enc_prepare w3, x5, x6
encrypt_block v4, w3, x5, x6, w7 /* first tweak */
dec_prepare w3, x2, x6
cbz w7, .Lxtsdecnotfirst
enc_prepare w3, x5, x8
encrypt_block v4, w3, x5, x8, w7 /* first tweak */
dec_prepare w3, x2, x8
ldr q7, .Lxts_mul_x
b .LxtsdecNx
.Lxtsdecnotfirst:
dec_prepare w3, x2, x8
.LxtsdecloopNx:
ldr q7, .Lxts_mul_x
next_tweak v4, v4, v7, v8
@@ -514,7 +515,7 @@ AES_ENTRY(aes_xts_decrypt)
.Lxtsdecloop:
ld1 {v1.16b}, [x1], #16
eor v0.16b, v1.16b, v4.16b
decrypt_block v0, w3, x2, x6, w7
decrypt_block v0, w3, x2, x8, w7
eor v0.16b, v0.16b, v4.16b
st1 {v0.16b}, [x0], #16
subs w4, w4, #1
@@ -522,6 +523,7 @@ AES_ENTRY(aes_xts_decrypt)
next_tweak v4, v4, v7, v8
b .Lxtsdecloop
.Lxtsdecout:
st1 {v4.16b}, [x6]
FRAME_POP
ret
AES_ENDPROC(aes_xts_decrypt)

View File

@@ -46,10 +46,9 @@ asmlinkage void aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[],
/* borrowed from aes-neon-blk.ko */
asmlinkage void neon_aes_ecb_encrypt(u8 out[], u8 const in[], u32 const rk[],
int rounds, int blocks, int first);
int rounds, int blocks);
asmlinkage void neon_aes_cbc_encrypt(u8 out[], u8 const in[], u32 const rk[],
int rounds, int blocks, u8 iv[],
int first);
int rounds, int blocks, u8 iv[]);
struct aesbs_ctx {
u8 rk[13 * (8 * AES_BLOCK_SIZE) + 32];
@@ -100,9 +99,8 @@ static int __ecb_crypt(struct skcipher_request *req,
struct skcipher_walk walk;
int err;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
while (walk.nbytes >= AES_BLOCK_SIZE) {
unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
@@ -110,12 +108,13 @@ static int __ecb_crypt(struct skcipher_request *req,
blocks = round_down(blocks,
walk.stride / AES_BLOCK_SIZE);
kernel_neon_begin();
fn(walk.dst.virt.addr, walk.src.virt.addr, ctx->rk,
ctx->rounds, blocks);
kernel_neon_end();
err = skcipher_walk_done(&walk,
walk.nbytes - blocks * AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -157,22 +156,21 @@ static int cbc_encrypt(struct skcipher_request *req)
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk walk;
int err, first = 1;
int err;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
while (walk.nbytes >= AES_BLOCK_SIZE) {
unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
/* fall back to the non-bitsliced NEON implementation */
kernel_neon_begin();
neon_aes_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
ctx->enc, ctx->key.rounds, blocks, walk.iv,
first);
ctx->enc, ctx->key.rounds, blocks,
walk.iv);
kernel_neon_end();
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
first = 0;
}
kernel_neon_end();
return err;
}
@@ -183,9 +181,8 @@ static int cbc_decrypt(struct skcipher_request *req)
struct skcipher_walk walk;
int err;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
while (walk.nbytes >= AES_BLOCK_SIZE) {
unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
@@ -193,13 +190,14 @@ static int cbc_decrypt(struct skcipher_request *req)
blocks = round_down(blocks,
walk.stride / AES_BLOCK_SIZE);
kernel_neon_begin();
aesbs_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
ctx->key.rk, ctx->key.rounds, blocks,
walk.iv);
kernel_neon_end();
err = skcipher_walk_done(&walk,
walk.nbytes - blocks * AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -231,9 +229,8 @@ static int ctr_encrypt(struct skcipher_request *req)
u8 buf[AES_BLOCK_SIZE];
int err;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
kernel_neon_begin();
while (walk.nbytes > 0) {
unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
u8 *final = (walk.total % AES_BLOCK_SIZE) ? buf : NULL;
@@ -244,8 +241,10 @@ static int ctr_encrypt(struct skcipher_request *req)
final = NULL;
}
kernel_neon_begin();
aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
ctx->rk, ctx->rounds, blocks, walk.iv, final);
kernel_neon_end();
if (final) {
u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
@@ -260,8 +259,6 @@ static int ctr_encrypt(struct skcipher_request *req)
err = skcipher_walk_done(&walk,
walk.nbytes - blocks * AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}
@@ -306,14 +303,13 @@ static int __xts_crypt(struct skcipher_request *req,
struct skcipher_walk walk;
int err;
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
if (err)
return err;
kernel_neon_begin();
neon_aes_ecb_encrypt(walk.iv, walk.iv, ctx->twkey,
ctx->key.rounds, 1, 1);
neon_aes_ecb_encrypt(walk.iv, walk.iv, ctx->twkey, ctx->key.rounds, 1);
kernel_neon_end();
while (walk.nbytes >= AES_BLOCK_SIZE) {
unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
@@ -322,13 +318,13 @@ static int __xts_crypt(struct skcipher_request *req,
blocks = round_down(blocks,
walk.stride / AES_BLOCK_SIZE);
kernel_neon_begin();
fn(walk.dst.virt.addr, walk.src.virt.addr, ctx->key.rk,
ctx->key.rounds, blocks, walk.iv);
kernel_neon_end();
err = skcipher_walk_done(&walk,
walk.nbytes - blocks * AES_BLOCK_SIZE);
}
kernel_neon_end();
return err;
}

View File

@@ -37,12 +37,19 @@ static void chacha20_doneon(u32 *state, u8 *dst, const u8 *src,
u8 buf[CHACHA_BLOCK_SIZE];
while (bytes >= CHACHA_BLOCK_SIZE * 4) {
kernel_neon_begin();
chacha20_4block_xor_neon(state, dst, src);
kernel_neon_end();
bytes -= CHACHA_BLOCK_SIZE * 4;
src += CHACHA_BLOCK_SIZE * 4;
dst += CHACHA_BLOCK_SIZE * 4;
state[12] += 4;
}
if (!bytes)
return;
kernel_neon_begin();
while (bytes >= CHACHA_BLOCK_SIZE) {
chacha20_block_xor_neon(state, dst, src);
bytes -= CHACHA_BLOCK_SIZE;
@@ -55,6 +62,7 @@ static void chacha20_doneon(u32 *state, u8 *dst, const u8 *src,
chacha20_block_xor_neon(state, buf, buf);
memcpy(dst, buf, bytes);
}
kernel_neon_end();
}
static int chacha20_neon(struct skcipher_request *req)
@@ -68,11 +76,10 @@ static int chacha20_neon(struct skcipher_request *req)
if (!may_use_simd() || req->cryptlen <= CHACHA_BLOCK_SIZE)
return crypto_chacha_crypt(req);
err = skcipher_walk_virt(&walk, req, true);
err = skcipher_walk_virt(&walk, req, false);
crypto_chacha_init(state, ctx, walk.iv);
kernel_neon_begin();
while (walk.nbytes > 0) {
unsigned int nbytes = walk.nbytes;
@@ -83,7 +90,6 @@ static int chacha20_neon(struct skcipher_request *req)
nbytes);
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
}
kernel_neon_end();
return err;
}

View File

@@ -444,7 +444,7 @@ static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par,
* making sure it is a kernel address and not a PC-relative
* reference.
*/
asm volatile("ldr %0, =__hyp_panic_string" : "=r" (str_va));
asm volatile("ldr %0, =%1" : "=r" (str_va) : "S" (__hyp_panic_string));
__hyp_do_panic(str_va,
spsr, elr,

View File

@@ -126,6 +126,7 @@ static void *map_vdso(const char *path, size_t *_size)
if (fstat(fd, &stat) != 0) {
fprintf(stderr, "%s: Failed to stat '%s': %s\n", program_name,
path, strerror(errno));
close(fd);
return NULL;
}
@@ -134,6 +135,7 @@ static void *map_vdso(const char *path, size_t *_size)
if (addr == MAP_FAILED) {
fprintf(stderr, "%s: Failed to map '%s': %s\n", program_name,
path, strerror(errno));
close(fd);
return NULL;
}
@@ -143,6 +145,7 @@ static void *map_vdso(const char *path, size_t *_size)
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
fprintf(stderr, "%s: '%s' is not an ELF file\n", program_name,
path);
close(fd);
return NULL;
}
@@ -154,6 +157,7 @@ static void *map_vdso(const char *path, size_t *_size)
default:
fprintf(stderr, "%s: '%s' has invalid ELF class\n",
program_name, path);
close(fd);
return NULL;
}
@@ -165,6 +169,7 @@ static void *map_vdso(const char *path, size_t *_size)
default:
fprintf(stderr, "%s: '%s' has invalid ELF data order\n",
program_name, path);
close(fd);
return NULL;
}
@@ -172,15 +177,18 @@ static void *map_vdso(const char *path, size_t *_size)
fprintf(stderr,
"%s: '%s' has invalid ELF machine (expected EM_MIPS)\n",
program_name, path);
close(fd);
return NULL;
} else if (swap_uint16(ehdr->e_type) != ET_DYN) {
fprintf(stderr,
"%s: '%s' has invalid ELF type (expected ET_DYN)\n",
program_name, path);
close(fd);
return NULL;
}
*_size = stat.st_size;
close(fd);
return addr;
}
@@ -284,10 +292,12 @@ int main(int argc, char **argv)
/* Calculate and write symbol offsets to <output file> */
if (!get_symbols(dbg_vdso_path, dbg_vdso)) {
unlink(out_path);
fclose(out_file);
return EXIT_FAILURE;
}
fprintf(out_file, "};\n");
fclose(out_file);
return EXIT_SUCCESS;
}

View File

@@ -189,7 +189,7 @@ __init_LPCR_ISA300:
__init_FSCR:
mfspr r3,SPRN_FSCR
ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB
ori r3,r3,FSCR_TAR|FSCR_EBB
mtspr SPRN_FSCR,r3
blr

View File

@@ -2095,6 +2095,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
if (perf_event_overflow(event, &data, regs))
power_pmu_stop(event, 0);
} else if (period) {
/* Account for interrupt in case of invalid SIAR */
if (perf_event_account_interrupt(event))
power_pmu_stop(event, 0);
}
}

View File

@@ -46,6 +46,7 @@ config SPU_FS
tristate "SPU file system"
default m
depends on PPC_CELL
depends on COREDUMP
select SPU_BASE
help
The SPU file system is used to access Synergistic Processing

View File

@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/cpumask.h>
#include <linux/mm.h>
#include <linux/kmemleak.h>
#include <asm/prom.h>
#include <asm/io.h>
@@ -630,6 +631,7 @@ static bool xive_native_provision_pages(void)
pr_err("Failed to allocate provisioning page\n");
return false;
}
kmemleak_ignore(p);
opal_xive_donate_page(chip, __pa(p));
}
return true;

View File

@@ -509,7 +509,7 @@ CONFIG_HARDENED_USERCOPY=y
CONFIG_STATIC_USERMODEHELPER=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
CONFIG_INIT_STACK_ALL=y
CONFIG_INIT_STACK_ALL_ZERO=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
CONFIG_CRYPTO_ADIANTUM=y

View File

@@ -3088,12 +3088,6 @@ static void binder_transaction(struct binder_proc *proc,
goto err_dead_binder;
}
e->to_node = target_node->debug_id;
if (WARN_ON(proc == target_proc)) {
return_error = BR_FAILED_REPLY;
return_error_param = -EINVAL;
return_error_line = __LINE__;
goto err_invalid_target_handle;
}
if (security_binder_transaction(proc->tsk,
target_proc->tsk) < 0) {
return_error = BR_FAILED_REPLY;
@@ -3696,17 +3690,10 @@ static int binder_thread_write(struct binder_proc *proc,
struct binder_node *ctx_mgr_node;
mutex_lock(&context->context_mgr_node_lock);
ctx_mgr_node = context->binder_context_mgr_node;
if (ctx_mgr_node) {
if (ctx_mgr_node->proc == proc) {
binder_user_error("%d:%d context manager tried to acquire desc 0\n",
proc->pid, thread->pid);
mutex_unlock(&context->context_mgr_node_lock);
return -EINVAL;
}
if (ctx_mgr_node)
ret = binder_inc_ref_for_node(
proc, ctx_mgr_node,
strong, NULL, &rdata);
}
mutex_unlock(&context->context_mgr_node_lock);
}
if (ret)

View File

@@ -3079,9 +3079,9 @@ static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
*/
void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
{
if (fwnode) {
struct fwnode_handle *fn = dev->fwnode;
struct fwnode_handle *fn = dev->fwnode;
if (fwnode) {
if (fwnode_is_primary(fn))
fn = fn->secondary;
@@ -3091,8 +3091,12 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
}
dev->fwnode = fwnode;
} else {
dev->fwnode = fwnode_is_primary(dev->fwnode) ?
dev->fwnode->secondary : NULL;
if (fwnode_is_primary(fn)) {
dev->fwnode = fn->secondary;
fn->secondary = NULL;
} else {
dev->fwnode = NULL;
}
}
}
EXPORT_SYMBOL_GPL(set_primary_fwnode);

View File

@@ -1474,13 +1474,17 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
}
/*
* If a device configured to wake up the system from sleep states
* has been suspended at run time and there's a resume request pending
* for it, this is equivalent to the device signaling wakeup, so the
* system suspend operation should be aborted.
* Wait for possible runtime PM transitions of the device in progress
* to complete and if there's a runtime resume request pending for it,
* resume it before proceeding with invoking the system-wide suspend
* callbacks for it.
*
* If the system-wide suspend callbacks below change the configuration
* of the device, they must disable runtime PM for it or otherwise
* ensure that its runtime-resume callbacks will not be confused by that
* change in case they are invoked going forward.
*/
if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
pm_wakeup_event(dev, 0);
pm_runtime_barrier(dev);
if (pm_wakeup_pending()) {
pm_get_active_wakeup_sources(suspend_abort,

View File

@@ -1135,7 +1135,7 @@ static int null_handle_rq(struct nullb_cmd *cmd)
len = bvec.bv_len;
err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset,
op_is_write(req_op(rq)), sector,
req_op(rq) & REQ_FUA);
rq->cmd_flags & REQ_FUA);
if (err) {
spin_unlock_irq(&nullb->lock);
return err;

View File

@@ -247,13 +247,8 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
chip->cdev.owner = THIS_MODULE;
chip->cdevs.owner = THIS_MODULE;
chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
if (!chip->work_space.context_buf) {
rc = -ENOMEM;
goto out;
}
chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
if (!chip->work_space.session_buf) {
rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);
if (rc) {
rc = -ENOMEM;
goto out;
}

View File

@@ -174,6 +174,7 @@ struct tpm_space {
u8 *context_buf;
u32 session_tbl[3];
u8 *session_buf;
u32 buf_size;
};
enum tpm_chip_flags {
@@ -261,6 +262,9 @@ struct tpm_output_header {
#define TPM_TAG_RQU_COMMAND 193
/* TPM2 specific constants. */
#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */
struct stclear_flags_t {
__be16 tag;
u8 deactivated;
@@ -583,7 +587,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm2_probe(struct tpm_chip *chip);
int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
int tpm2_init_space(struct tpm_space *space);
int tpm2_init_space(struct tpm_space *space, unsigned int buf_size);
void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
u8 *cmd);

View File

@@ -44,18 +44,21 @@ static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
}
}
int tpm2_init_space(struct tpm_space *space)
int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
{
space->context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
space->context_buf = kzalloc(buf_size, GFP_KERNEL);
if (!space->context_buf)
return -ENOMEM;
space->session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
space->session_buf = kzalloc(buf_size, GFP_KERNEL);
if (space->session_buf == NULL) {
kfree(space->context_buf);
/* Prevent caller getting a dangling pointer. */
space->context_buf = NULL;
return -ENOMEM;
}
space->buf_size = buf_size;
return 0;
}
@@ -278,8 +281,10 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
sizeof(space->context_tbl));
memcpy(&chip->work_space.session_tbl, &space->session_tbl,
sizeof(space->session_tbl));
memcpy(chip->work_space.context_buf, space->context_buf, PAGE_SIZE);
memcpy(chip->work_space.session_buf, space->session_buf, PAGE_SIZE);
memcpy(chip->work_space.context_buf, space->context_buf,
space->buf_size);
memcpy(chip->work_space.session_buf, space->session_buf,
space->buf_size);
rc = tpm2_load_space(chip);
if (rc) {
@@ -459,7 +464,7 @@ static int tpm2_save_space(struct tpm_chip *chip)
continue;
rc = tpm2_save_context(chip, space->context_tbl[i],
space->context_buf, PAGE_SIZE,
space->context_buf, space->buf_size,
&offset);
if (rc == -ENOENT) {
space->context_tbl[i] = 0;
@@ -478,9 +483,8 @@ static int tpm2_save_space(struct tpm_chip *chip)
continue;
rc = tpm2_save_context(chip, space->session_tbl[i],
space->session_buf, PAGE_SIZE,
space->session_buf, space->buf_size,
&offset);
if (rc == -ENOENT) {
/* handle error saving session, just forget it */
space->session_tbl[i] = 0;
@@ -526,8 +530,10 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
sizeof(space->context_tbl));
memcpy(&space->session_tbl, &chip->work_space.session_tbl,
sizeof(space->session_tbl));
memcpy(space->context_buf, chip->work_space.context_buf, PAGE_SIZE);
memcpy(space->session_buf, chip->work_space.session_buf, PAGE_SIZE);
memcpy(space->context_buf, chip->work_space.context_buf,
space->buf_size);
memcpy(space->session_buf, chip->work_space.session_buf,
space->buf_size);
return 0;
}

View File

@@ -22,7 +22,7 @@ static int tpmrm_open(struct inode *inode, struct file *file)
if (priv == NULL)
return -ENOMEM;
rc = tpm2_init_space(&priv->space);
rc = tpm2_init_space(&priv->space, TPM2_SPACE_BUFFER_SIZE);
if (rc) {
kfree(priv);
return -ENOMEM;

View File

@@ -147,6 +147,8 @@
(n << (28 + (2 * skl) - PAGE_SHIFT))
static int nr_channels;
static struct pci_dev *mci_pdev;
static int ie31200_registered = 1;
struct ie31200_priv {
void __iomem *window;
@@ -518,12 +520,16 @@ fail_free:
static int ie31200_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
edac_dbg(0, "MC:\n");
int rc;
edac_dbg(0, "MC:\n");
if (pci_enable_device(pdev) < 0)
return -EIO;
rc = ie31200_probe1(pdev, ent->driver_data);
if (rc == 0 && !mci_pdev)
mci_pdev = pci_dev_get(pdev);
return ie31200_probe1(pdev, ent->driver_data);
return rc;
}
static void ie31200_remove_one(struct pci_dev *pdev)
@@ -532,6 +538,8 @@ static void ie31200_remove_one(struct pci_dev *pdev)
struct ie31200_priv *priv;
edac_dbg(0, "\n");
pci_dev_put(mci_pdev);
mci_pdev = NULL;
mci = edac_mc_del_mc(&pdev->dev);
if (!mci)
return;
@@ -583,17 +591,53 @@ static struct pci_driver ie31200_driver = {
static int __init ie31200_init(void)
{
int pci_rc, i;
edac_dbg(3, "MC:\n");
/* Ensure that the OPSTATE is set correctly for POLL or NMI */
opstate_init();
return pci_register_driver(&ie31200_driver);
pci_rc = pci_register_driver(&ie31200_driver);
if (pci_rc < 0)
goto fail0;
if (!mci_pdev) {
ie31200_registered = 0;
for (i = 0; ie31200_pci_tbl[i].vendor != 0; i++) {
mci_pdev = pci_get_device(ie31200_pci_tbl[i].vendor,
ie31200_pci_tbl[i].device,
NULL);
if (mci_pdev)
break;
}
if (!mci_pdev) {
edac_dbg(0, "ie31200 pci_get_device fail\n");
pci_rc = -ENODEV;
goto fail1;
}
pci_rc = ie31200_init_one(mci_pdev, &ie31200_pci_tbl[i]);
if (pci_rc < 0) {
edac_dbg(0, "ie31200 init fail\n");
pci_rc = -ENODEV;
goto fail1;
}
}
return 0;
fail1:
pci_unregister_driver(&ie31200_driver);
fail0:
pci_dev_put(mci_pdev);
return pci_rc;
}
static void __exit ie31200_exit(void)
{
edac_dbg(3, "MC:\n");
pci_unregister_driver(&ie31200_driver);
if (!ie31200_registered)
ie31200_remove_one(mci_pdev);
}
module_init(ie31200_init);

View File

@@ -734,8 +734,10 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
if (encoder) {
@@ -872,8 +874,10 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
encoder = amdgpu_connector_best_single_encoder(connector);
@@ -996,8 +1000,10 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
@@ -1371,8 +1377,10 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {

View File

@@ -269,7 +269,7 @@ int amdgpu_crtc_set_config(struct drm_mode_set *set,
ret = pm_runtime_get_sync(dev->dev);
if (ret < 0)
return ret;
goto out;
ret = drm_crtc_helper_set_config(set, ctx);
@@ -284,7 +284,7 @@ int amdgpu_crtc_set_config(struct drm_mode_set *set,
take the current one */
if (active && !adev->have_disp_power_ref) {
adev->have_disp_power_ref = true;
return ret;
goto out;
}
/* if we have no active crtcs, then drop the power ref
we got before */
@@ -293,6 +293,7 @@ int amdgpu_crtc_set_config(struct drm_mode_set *set,
adev->have_disp_power_ref = false;
}
out:
/* drop the power reference we got coming in here */
pm_runtime_put_autosuspend(dev->dev);
return ret;

View File

@@ -801,11 +801,12 @@ long amdgpu_drm_ioctl(struct file *filp,
dev = file_priv->minor->dev;
ret = pm_runtime_get_sync(dev->dev);
if (ret < 0)
return ret;
goto out;
ret = drm_ioctl(filp, cmd, arg);
pm_runtime_mark_last_busy(dev->dev);
out:
pm_runtime_put_autosuspend(dev->dev);
return ret;
}

View File

@@ -502,8 +502,12 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
* in the bitfields */
if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
se_num = 0xffffffff;
else if (se_num >= AMDGPU_GFX_MAX_SE)
return -EINVAL;
if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK)
sh_num = 0xffffffff;
else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE)
return -EINVAL;
if (info->read_mmr_reg.count > 128)
return -EINVAL;
@@ -785,7 +789,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
r = pm_runtime_get_sync(dev->dev);
if (r < 0)
return r;
goto pm_put;
fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
if (unlikely(!fpriv)) {
@@ -824,6 +828,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
out_suspend:
pm_runtime_mark_last_busy(dev->dev);
pm_put:
pm_runtime_put_autosuspend(dev->dev);
return r;

View File

@@ -821,8 +821,10 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
ret = kobject_init_and_add(dev->kobj_node, &node_type,
sys_props.kobj_nodes, "%d", id);
if (ret < 0)
if (ret < 0) {
kobject_put(dev->kobj_node);
return ret;
}
dev->kobj_mem = kobject_create_and_add("mem_banks", dev->kobj_node);
if (!dev->kobj_mem)
@@ -865,8 +867,10 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
return -ENOMEM;
ret = kobject_init_and_add(mem->kobj, &mem_type,
dev->kobj_mem, "%d", i);
if (ret < 0)
if (ret < 0) {
kobject_put(mem->kobj);
return ret;
}
mem->attr.name = "properties";
mem->attr.mode = KFD_SYSFS_FILE_MODE;
@@ -884,8 +888,10 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
return -ENOMEM;
ret = kobject_init_and_add(cache->kobj, &cache_type,
dev->kobj_cache, "%d", i);
if (ret < 0)
if (ret < 0) {
kobject_put(cache->kobj);
return ret;
}
cache->attr.name = "properties";
cache->attr.mode = KFD_SYSFS_FILE_MODE;
@@ -903,8 +909,10 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
return -ENOMEM;
ret = kobject_init_and_add(iolink->kobj, &iolink_type,
dev->kobj_iolink, "%d", i);
if (ret < 0)
if (ret < 0) {
kobject_put(iolink->kobj);
return ret;
}
iolink->attr.name = "properties";
iolink->attr.mode = KFD_SYSFS_FILE_MODE;
@@ -956,8 +964,10 @@ static int kfd_topology_update_sysfs(void)
ret = kobject_init_and_add(sys_props.kobj_topology,
&sysprops_type, &kfd_device->kobj,
"topology");
if (ret < 0)
if (ret < 0) {
kobject_put(sys_props.kobj_topology);
return ret;
}
sys_props.kobj_nodes = kobject_create_and_add("nodes",
sys_props.kobj_topology);

View File

@@ -501,8 +501,7 @@ static bool drm_master_filter(char *task_name)
{
unsigned int i = 0;
bool ret = false;
//pr_debug("%s task_name:%s \n", __func__, task_name);
for (i=0; i<MAX_LIST_NUM; i++) {
for (i = 0; i < MAX_LIST_NUM; i++) {
if (!strncmp(task_name, support_list[i], strlen(support_list[i]))) {
ret = true;
break;
@@ -537,11 +536,10 @@ int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
/* MASTER is only for master or control clients */
if (unlikely((flags & DRM_MASTER) &&
!drm_is_current_master(file_priv) &&
!drm_is_control_client(file_priv))) {
if (!drm_master_filter(task->comm)) {
!drm_is_current_master(file_priv) &&
!drm_is_control_client(file_priv))) {
if (!drm_master_filter(task->comm))
return -EACCES;
}
}
/* Control clients must be explicitly allowed */

View File

@@ -978,15 +978,11 @@ int dsi_display_read_panel(struct dsi_panel *panel, struct dsi_read_config *read
} else
return -EINVAL;
if (!panel->panel_initialized) {
pr_info("Panel not initialized\n");
if (!panel->panel_initialized)
return -EINVAL;
}
if (!read_config->enabled) {
pr_info("read operation was not permitted\n");
if (!read_config->enabled)
return -EPERM;
}
dsi_display_clk_ctrl(display->dsi_clk_handle,
DSI_ALL_CLKS, DSI_CLK_ON);
@@ -1026,10 +1022,6 @@ int dsi_display_read_panel(struct dsi_panel *panel, struct dsi_read_config *read
goto exit;
}
for (i = 0; i < read_config->cmds_rlen; i++) //debug
pr_info("0x%x ", read_config->rbuf[i]);
pr_info("\n");
exit:
dsi_display_cmd_engine_disable(display);
exit_ctrl:
@@ -1263,7 +1255,6 @@ int dsi_display_set_power(struct drm_connector *connector,
}
g_notify_data.data = &event;
pr_debug("%s %d\n", __func__, event);
switch (power_mode) {
case SDE_MODE_DPMS_LP1:
msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, &g_notify_data);
@@ -7595,11 +7586,8 @@ int dsi_display_enable(struct dsi_display *display)
pr_err("Read elvss_dimming_cmds failed, rc=%d\n", rc);
return 0;
}
pr_info("elvss dimming read result %x\n", panel->elvss_dimming_cmds.rbuf[0]);
((u8 *)panel->hbm_fod_on.cmds[4].msg.tx_buf)[1] = (panel->elvss_dimming_cmds.rbuf[0]) & 0x7F;
pr_info("fod hbm on change to %x\n", ((u8 *)panel->hbm_fod_on.cmds[4].msg.tx_buf)[1]);
((u8 *)panel->hbm_fod_off.cmds[6].msg.tx_buf)[1] = panel->elvss_dimming_cmds.rbuf[0];
pr_info("fod hbm off change to %x\n", ((u8 *)panel->hbm_fod_off.cmds[6].msg.tx_buf)[1]);
}
dsi_panel_release_panel_lock(display->panel);

View File

@@ -198,10 +198,8 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge)
struct drm_device *dev = bridge->dev;
int event = 0;
if (dev->doze_state == MSM_DRM_BLANK_POWERDOWN) {
if (dev->doze_state == MSM_DRM_BLANK_POWERDOWN)
dev->doze_state = MSM_DRM_BLANK_UNBLANK;
pr_info("%s power on from power off\n", __func__);
}
event = dev->doze_state;
@@ -229,7 +227,6 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge)
msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, &g_notify_data);
dev->fp_quickon = false;
}
pr_info("%s panel already on\n", __func__);
return;
}
@@ -299,10 +296,8 @@ int dsi_bridge_interface_enable(int timeout)
ret = wait_event_timeout(resume_wait_q,
!atomic_read(&resume_pending),
msecs_to_jiffies(WAIT_RESUME_TIMEOUT));
if (!ret) {
pr_info("Primary fb resume timeout\n");
if (!ret)
return -ETIMEDOUT;
}
mutex_lock(&gbridge->base.lock);
@@ -468,10 +463,8 @@ static void dsi_bridge_post_disable(struct drm_bridge *bridge)
struct drm_device *dev = bridge->dev;
int event = 0;
if (dev->doze_state == MSM_DRM_BLANK_UNBLANK) {
if (dev->doze_state == MSM_DRM_BLANK_UNBLANK)
dev->doze_state = MSM_DRM_BLANK_POWERDOWN;
pr_info("%s wrong doze state\n", __func__);
}
event = dev->doze_state;

View File

@@ -31,7 +31,7 @@
#include <linux/msm_drm_notify.h>
#define DSI_READ_WRITE_PANEL_DEBUG 1
#define DSI_READ_WRITE_PANEL_DEBUG 0
#if DSI_READ_WRITE_PANEL_DEBUG
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
@@ -41,7 +41,6 @@
#include "dsi_panel_mi.h"
/**
* topology is currently defined by a set of following 3 values:
* 1. num of layer mixers
@@ -663,7 +662,7 @@ static int dsi_panel_update_backlight(struct dsi_panel *panel,
int rc = 0;
struct mipi_dsi_device *dsi;
if (!panel || (bl_lvl > panel->bl_config.bl_max_level)) {
if (!panel || (bl_lvl > 0xffff)) {
pr_err("invalid params\n");
return -EINVAL;
}
@@ -673,11 +672,8 @@ static int dsi_panel_update_backlight(struct dsi_panel *panel,
if (panel->bl_config.dcs_type_ss) {
if (0 == bl_lvl) {
dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_DIMMINGOFF);
if (panel->fod_dimlayer_enabled) {
if (panel->fod_dimlayer_enabled)
panel->fod_dimlayer_hbm_enabled = false;
pr_debug("set fod_dimlayer_hbm_enabled state:[%d], because bl_lvl is %d\n",
panel->fod_dimlayer_hbm_enabled, bl_lvl);
}
}
rc = mipi_dsi_dcs_set_display_brightness_ss(dsi, bl_lvl);
} else
@@ -755,18 +751,14 @@ int dsi_panel_set_doze_backlight(struct dsi_display *display)
drm_dev = dsi_display->drm_dev;
mutex_lock(&panel->panel_lock);
if (!dsi_panel_initialized(panel)) {
pr_info("[%s] set doze backlight before panel initialized!\n", dsi_display->name);
if (!dsi_panel_initialized(panel))
goto error;
}
if (drm_dev && (drm_dev->doze_state == MSM_DRM_BLANK_LP1 || drm_dev->doze_state == MSM_DRM_BLANK_LP2)) {
if (panel->fod_hbm_enabled || panel->fod_dimlayer_hbm_enabled || panel->fod_backlight_flag) {
pr_debug("%s FOD HBM open, skip set doze backlight at: [hbm=%d][dimlayer_fod=%d][fod_bl=%d]\n",
__func__, panel->fod_hbm_enabled,
panel->fod_dimlayer_hbm_enabled, panel->fod_backlight_flag);
if (drm_dev && (drm_dev->doze_state == MSM_DRM_BLANK_LP1 ||
drm_dev->doze_state == MSM_DRM_BLANK_LP2)) {
if (panel->fod_hbm_enabled || panel->fod_dimlayer_hbm_enabled ||
panel->fod_backlight_flag)
goto error;
}
if (drm_dev->doze_brightness == DOZE_BRIGHTNESS_HBM) {
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_HBM);
@@ -781,10 +773,8 @@ int dsi_panel_set_doze_backlight(struct dsi_display *display)
panel->name, rc);
panel->in_aod = true;
panel->skip_dimmingon = STATE_DIM_BLOCK;
} else {
} else
drm_dev->doze_brightness = DOZE_BRIGHTNESS_INVALID;
pr_debug("In %s the doze_brightness value:%u\n", __func__, drm_dev->doze_brightness);
}
}
error:
@@ -810,13 +800,25 @@ ssize_t dsi_panel_get_doze_backlight(struct dsi_display *display, char *buf)
mutex_lock(&panel->panel_lock);
rc = snprintf(buf, PAGE_SIZE, "%d\n", drm_dev->doze_brightness);
pr_info("In %s the doze_brightness value:%u\n", __func__, drm_dev->doze_brightness);
mutex_unlock(&panel->panel_lock);
return rc;
}
bool dc_skip_set_backlight(struct dsi_panel *panel, u32 bl_lvl)
{
/* 1. dc enable is 1;
* 2. bl_lvl should be less than dc threshold;
* 3. bl_lvl is not 0, we should not skip set 0;
* When meet all the 3 conditions at the same time, skip set bl.
*/
if (panel->dc_enable &&
(bl_lvl < panel->dc_threshold) && (bl_lvl != 0))
return true;
else
return false;
}
int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl)
{
int rc = 0;
@@ -826,31 +828,35 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl)
if (panel->host_config.ext_bridge_num)
return 0;
pr_debug("backlight type:%d lvl:%d\n", bl->type, bl_lvl);
if (0 == bl_lvl)
if (bl_lvl == 0)
dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_DIMMINGOFF);
if (panel->bl_config.bl_remap_flag && panel->bl_config.brightness_max_level
&& panel->bl_config.bl_max_level) {
/* map UI brightness into driver backlight level
* y = kx+b;
*/
bl_temp = (panel->bl_config.bl_max_level - panel->bl_config.bl_min_level)*bl_lvl/panel->bl_config.brightness_max_level
+ panel->bl_config.bl_min_level;
} else
bl_temp = bl_lvl;
/* Restore to last_bl_lvl to avoid flash high brightness
* white exiting app lock with DC on (MIUI-1755728),
* must make sure last_bl_lvl is correct. */
if (panel->fod_dimlayer_bl_block) {
panel->last_bl_lvl = bl_lvl;
}
if (dc_skip_set_backlight(panel, bl_lvl))
return rc;
if (panel->fod_flag &&
(panel->last_bl_lvl == 0) && (bl_lvl != 0) &&
(!panel->fod_dimlayer_hbm_enabled) && panel->fod_dimlayer_enabled) {
panel->fod_dimlayer_bl_block = true;
panel->last_bl_lvl = bl_lvl;
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CRC_OFF);
return rc;
}
switch (bl->type) {
case DSI_BACKLIGHT_WLED:
rc = backlight_device_set_brightness(bl->raw_bd, bl_temp);
rc = backlight_device_set_brightness(bl->raw_bd, bl_lvl);
break;
case DSI_BACKLIGHT_DCS:
if (panel->fod_backlight_flag) {
pr_debug("fod_backlight_flag set\n");
} else {
rc = dsi_panel_update_backlight(panel, bl_temp);
}
if (!panel->fod_backlight_flag)
rc = dsi_panel_update_backlight(panel, bl_lvl);
break;
case DSI_BACKLIGHT_EXTERNAL:
break;
@@ -871,15 +877,12 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl)
panel->skip_dimmingon = STATE_NONE;
}
if (bl_lvl > 0 && panel->last_bl_lvl == 0) {
pr_debug("crc off when quickly power on\n");
if (bl_lvl > 0 && panel->last_bl_lvl == 0)
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CRC_OFF);
}
if (bl_lvl == 0) {
pr_debug("DC off when last backlight is 0\n");
if (bl_lvl == 0)
panel->dc_enable = false;
}
panel->last_bl_lvl = bl_lvl;
return rc;
}
@@ -2568,9 +2571,6 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel)
panel->bl_config.brightness_default_level = val;
}
panel->bl_config.bl_remap_flag = utils->read_bool(utils->data,
"qcom,mdss-brightness-remap");
if (panel->bl_config.type == DSI_BACKLIGHT_PWM) {
rc = dsi_panel_parse_bl_pwm_config(panel);
if (rc) {
@@ -3597,7 +3597,7 @@ static int dsi_panel_parse_mi_config(struct dsi_panel *panel,
utils = &panel->utils;
dispparam_enabled = utils->read_bool(of_node,
"qcom,dispparam-enabled");
"qcom,dispparam-enabled");
if (dispparam_enabled){
pr_info("[LCD]%s:%d Dispparam enabled.\n", __func__, __LINE__);
panel->dispparam_enabled = true;
@@ -3647,11 +3647,6 @@ static int dsi_panel_parse_mi_config(struct dsi_panel *panel,
panel->fod_dimlayer_enabled = utils->read_bool(of_node,
"qcom,mdss-dsi-panel-fod-dimlayer-enabled");
if (panel->fod_dimlayer_enabled) {
pr_info("fod dimlayer enabled.\n");
} else {
pr_info("fod dimlayer disabled.\n");
}
dsi_panel_parse_elvss_dimming_config(panel);
@@ -3879,7 +3874,6 @@ error:
return rc;
}
ssize_t mipi_reg_write(char *buf, size_t count)
{
struct dsi_panel *panel = g_panel;
@@ -4143,8 +4137,6 @@ int dsi_panel_drv_init(struct dsi_panel *panel,
#if DSI_READ_WRITE_PANEL_DEBUG
mipi_proc_entry = proc_create(MIPI_PROC_NAME, 0664, NULL, &mipi_reg_proc_fops);
if (!mipi_proc_entry)
printk(KERN_WARNING "mipi_reg: unable to create proc entry.\n");
#endif
goto exit;
@@ -4519,7 +4511,6 @@ int dsi_panel_set_lp1(struct dsi_panel *panel)
pr_err("invalid params\n");
return -EINVAL;
}
pr_info("%s\n", __func__);
mutex_lock(&panel->panel_lock);
/**
@@ -4590,7 +4581,6 @@ int dsi_panel_set_lp2(struct dsi_panel *panel)
pr_err("invalid params\n");
return -EINVAL;
}
pr_info("%s\n", __func__);
mutex_lock(&panel->panel_lock);
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_LP2);
@@ -4609,18 +4599,19 @@ int dsi_panel_set_nolp(struct dsi_panel *panel)
pr_err("invalid params\n");
return -EINVAL;
}
pr_debug("%s\n", __func__);
mutex_lock(&panel->panel_lock);
if (!panel->fod_hbm_enabled && !panel->fod_dimlayer_hbm_enabled) {
if (panel->fod_flag && panel->fod_dimlayer_enabled) {
dsi_panel_update_backlight(panel, 0);
panel->fod_dimlayer_bl_block = true;
}
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_NOLP);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_NOLP cmd, rc=%d\n",
panel->name, rc);
panel->skip_dimmingon = STATE_NONE;
} else
pr_debug("%s skip\n", __func__);
}
panel->in_aod = false;
/**
@@ -4883,8 +4874,6 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
mutex_lock(&panel->panel_lock);
pr_debug("[LCD] param_type=%d\n", param);
if (!panel->panel_initialized
&& (param & 0x0F000000) != DISPPARAM_FOD_BACKLIGHT_ON
&& (param & 0x0F000000) != DISPPARAM_FOD_BACKLIGHT_OFF) {
@@ -4901,47 +4890,36 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
temp = param & 0x0000000F;
switch (temp) {
case DISPPARAM_WARM:
pr_info("warm\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_WARM);
break;
case DISPPARAM_DEFAULT:
pr_info("normal\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_DEFAULT);
break;
case DISPPARAM_COLD:
pr_info("cold\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_COLD);
break;
case DISPPARAM_PAPERMODE8:
pr_info("paper mode\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_COLD);
break;
case DISPPARAM_PAPERMODE1:
pr_info("paper mode 1\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_PAPER1);
break;
case DISPPARAM_PAPERMODE2:
pr_info("paper mode 2\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_PAPER2);
break;
case DISPPARAM_PAPERMODE3:
pr_info("paper mode 3\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_PAPER3);
break;
case DISPPARAM_PAPERMODE4:
pr_info("paper mode 4\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_PAPER4);
break;
case DISPPARAM_PAPERMODE5:
pr_info("paper mode 5\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_PAPER5);
break;
case DISPPARAM_PAPERMODE6:
pr_info("paper mode 6\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_PAPER6);
break;
case DISPPARAM_PAPERMODE7:
pr_info("paper mode 7\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_PAPER7);
break;
default:
@@ -4951,11 +4929,9 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
temp = param & 0x000000F0;
switch (temp) {
case DISPPARAM_CE_ON:
pr_info("ceon\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CEON);
break;
case DISPPARAM_CE_OFF:
pr_info("ceoff\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CEOFF);
break;
default:
@@ -4965,52 +4941,37 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
temp = param & 0x00000F00;
switch (temp) {
case DISPPARAM_CABCUI_ON:
pr_info("cabcuion\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CABCUION);
break;
case DISPPARAM_CABCSTILL_ON:
pr_info("cabcstillon\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CABCSTILLON);
break;
case DISPPARAM_CABCMOVIE_ON:
pr_info("cabcmovieon\n");
dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CABCMOVIEON);
break;
case DISPPARAM_CABC_OFF:
pr_info("cabcoff\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CABCOFF);
break;
case DISPPARAM_SKIN_CE_CABCUI_ON:
pr_info("skince cabcuion\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_SKINCE_CABCUION);
break;
case DISPPARAM_SKIN_CE_CABCSTILL_ON:
pr_info("skince cabcstillon\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_SKINCE_CABCSTILLON);
break;
case DISPPARAM_SKIN_CE_CABCMOVIE_ON:
pr_info("skince cabcmovieon\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_SKINCE_CABCMOVIEON);
break;
case DISPPARAM_SKIN_CE_CABC_OFF:
pr_info("skince cabcoff\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_SKINCE_CABCOFF);
break;
case DISPPARAM_DIMMING_OFF:
pr_debug("dimmingoff\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_DIMMINGOFF);
break;
case DISPPARAM_DIMMING:
pr_debug("dimmingon\n");
if (panel->skip_dimmingon != STATE_DIM_BLOCK) {
if (ktime_after(ktime_get(), panel->fod_hbm_off_time)
&& ktime_after(ktime_get(), panel->fod_backlight_off_time)) {
&& ktime_after(ktime_get(), panel->fod_backlight_off_time))
dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_DIMMINGON);
} else {
pr_debug("skip dimmingon due to hbm off\n");
}
} else {
pr_debug("skip dimmingon due to hbm on\n");
}
break;
default:
@@ -5020,19 +4981,15 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
temp = param & 0x0000F000;
switch (temp) {
case DISPPARAM_ACL_L1:
pr_info("acl level 1\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_ACL_L1);
break;
case DISPPARAM_ACL_L2:
pr_info("acl level 2\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_ACL_L2);
break;
case DISPPARAM_ACL_L3:
pr_info("acl level 3\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_ACL_L3);
break;
case DISPPARAM_ACL_OFF:
pr_info("acl off\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_ACL_OFF);
break;
default:
@@ -5042,13 +4999,11 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
temp = param & 0x000F0000;
switch (temp) {
case DISPPARAM_HBM_ON:
pr_debug("hbm on\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_HBM_ON);
panel->skip_dimmingon = STATE_DIM_BLOCK;
panel->hbm_enabled = true;
break;
case DISPPARAM_HBM_FOD_ON:
pr_debug("hbm fod on\n");
if (panel->elvss_dimming_check_enable) {
rc = dsi_display_write_panel(panel, &panel->hbm_fod_on);
} else {
@@ -5058,19 +5013,15 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
panel->fod_hbm_enabled = true;
break;
case DISPPARAM_HBM_FOD2NORM:
pr_debug("hbm fod to normal mode\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_HBM_FOD2NORM);
break;
case DISPPARAM_DC_ON:
pr_info("DC on\n");
panel->dc_enable = true;
break;
case DISPPARAM_DC_OFF:
pr_info("DC off\n");
panel->dc_enable = false;
break;
case DISPPARAM_HBM_FOD_OFF:
pr_debug("hbm fod off\n");
if (panel->elvss_dimming_check_enable) {
rc = dsi_display_write_panel(panel, &panel->hbm_fod_off);
} else {
@@ -5088,31 +5039,6 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
if ((display->drm_dev && display->drm_dev->doze_state == MSM_DRM_BLANK_LP1) ||
(display->drm_dev && display->drm_dev->doze_state == MSM_DRM_BLANK_LP2)) {
#if 0
if (panel->last_bl_lvl > panel->doze_backlight_threshold) {
pr_info("hbm fod off DSI_CMD_SET_DOZE_HBM");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_HBM);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_DOZE_HBM cmd, rc=%d\n",
panel->name, rc);
display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_HBM;
panel->in_aod = true;
panel->skip_dimmingon = STATE_DIM_BLOCK;
} else if (panel->last_bl_lvl <= panel->doze_backlight_threshold && panel->last_bl_lvl > 0) {
pr_info("hbm fod off DSI_CMD_SET_DOZE_LBM");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_LBM);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_DOZE_LBM cmd, rc=%d\n",
panel->name, rc);
display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_LBM;
panel->in_aod = true;
panel->skip_dimmingon = STATE_DIM_BLOCK;
} else {
pr_info("hbm fod off DOZE_BRIGHTNESS_INVALID");
display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_INVALID;
}
#else
pr_info("HBM_FOD_OFF DSI_CMD_SET_DOZE_HBM");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_HBM);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_DOZE_HBM cmd, rc=%d\n",
@@ -5120,12 +5046,10 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_HBM;
panel->in_aod = true;
panel->skip_dimmingon = STATE_DIM_BLOCK;
#endif
}
}
break;
case DISPPARAM_HBM_OFF:
pr_info("hbm off\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_HBM_OFF);
panel->skip_dimmingon = STATE_DIM_RESTORE;
panel->hbm_enabled = false;
@@ -5137,36 +5061,32 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
temp = param & 0x00F00000;
switch (temp) {
case DISPPARAM_NORMALMODE1:
pr_info("normal mode1\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_NORMAL1);
break;
case DISPPARAM_P3:
pr_info("dci p3 mode\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CRC_DCIP3);
break;
case DISPPARAM_SRGB:
pr_info("sRGB\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_SRGB);
break;
case DISPPARAM_DOZE_BRIGHTNESS_HBM:
if (panel->in_aod) {
pr_info("doze hbm On\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_HBM);
panel->skip_dimmingon = STATE_DIM_BLOCK;
}
break;
case DISPPARAM_DOZE_BRIGHTNESS_LBM:
if (panel->in_aod) {
pr_info("doze lbm On\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_LBM);
panel->skip_dimmingon = STATE_DIM_BLOCK;
}
break;
case DISPPARAM_DOZE_OFF:
pr_info("doze Off\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_NOLP);
break;
case DISPPARAM_HBM_BACKLIGHT_RESEND:
if (panel->fod_dimlayer_bl_block)
break;
{
backlight_delta++;
@@ -5190,16 +5110,6 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
}
break;
case DISPPARAM_FOD_BACKLIGHT:
pr_debug("FOD backlight");
if (strnstr(panel->name, "ea8076", 20)) {
pr_debug("FOD ea8076\n");
} else if (strnstr(panel->name, "r66456", 20)) {
pr_debug("FOD r66456\n");
if (fod_backlight == 0x690)
fod_backlight = 4090;
else if (fod_backlight == 0x7FF)
fod_backlight = 4090;
}
if (fod_backlight == 0x1000) {
struct dsi_display *display = NULL;
struct mipi_dsi_host *host = panel->host;
@@ -5209,43 +5119,13 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
pr_debug("FOD backlight restore last_bl_lvl=%d, doze_state=%d",
panel->last_bl_lvl, display->drm_dev->doze_state);
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_DIMMINGOFF);
if (panel->dc_enable) {
pr_info("FOD backlight restore dc_threshold=%d, doze_state=%d",
panel->dc_threshold, display->drm_dev->doze_state);
if (panel->dc_enable)
rc = dsi_panel_update_backlight(panel, panel->dc_threshold);
} else {
pr_info("FOD backlight restore last_bl_lvl=%d, doze_state=%d",
panel->last_bl_lvl, display->drm_dev->doze_state);
else
rc = dsi_panel_update_backlight(panel, panel->last_bl_lvl);
}
if ((display->drm_dev && display->drm_dev->doze_state == MSM_DRM_BLANK_LP1) ||
(display->drm_dev && display->drm_dev->doze_state == MSM_DRM_BLANK_LP2)) {
#if 0
if (panel->last_bl_lvl > panel->doze_backlight_threshold) {
pr_info("FOD backlight restore DSI_CMD_SET_DOZE_HBM");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_HBM);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_DOZE_HBM cmd, rc=%d\n",
panel->name, rc);
display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_HBM;
panel->in_aod = true;
panel->skip_dimmingon = STATE_DIM_BLOCK;
} else if (panel->last_bl_lvl <= panel->doze_backlight_threshold && panel->last_bl_lvl > 0) {
pr_info("FOD backlight restore DSI_CMD_SET_DOZE_LBM");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_LBM);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_DOZE_LBM cmd, rc=%d\n",
panel->name, rc);
display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_LBM;
panel->in_aod = true;
panel->skip_dimmingon = STATE_DIM_BLOCK;
} else {
pr_info("FOD backlight restore DOZE_BRIGHTNESS_INVALID");
display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_INVALID;
}
#else
pr_info("FOD backlight restore DSI_CMD_SET_DOZE_HBM");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_HBM);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_DOZE_HBM cmd, rc=%d\n",
@@ -5253,13 +5133,11 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_HBM;
panel->in_aod = true;
panel->skip_dimmingon = STATE_DIM_BLOCK;
#endif
} else {
panel->skip_dimmingon = STATE_DIM_RESTORE;
panel->fod_backlight_off_time = ktime_add_ms(ktime_get(), panel->fod_off_dimming_delay);
}
} else if (fod_backlight >= 0) {
pr_debug("FOD backlight set");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_DIMMINGOFF);
rc = dsi_panel_update_backlight(panel, fod_backlight);
panel->fod_target_backlight = fod_backlight;
@@ -5267,7 +5145,6 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
}
break;
case DISPPARAM_CRC_OFF:
pr_debug("crc off\n");
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_CRC_OFF);
break;
default:
@@ -5277,21 +5154,17 @@ static int panel_disp_param_send_lock(struct dsi_panel *panel, int param)
temp = param & 0x0F000000;
switch (temp) {
case DISPPARAM_FOD_BACKLIGHT_ON:
pr_debug("fod_backlight_flag on\n");
panel->fod_backlight_flag = true;
break;
case DISPPARAM_FOD_BACKLIGHT_OFF:
pr_debug("fod_backlight_flag off\n");
panel->fod_backlight_flag = false;
break;
case DISPPARAM_ELVSS_DIMMING_ON:
pr_info("elvss dimming on\n");
((u8 *)panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_ELVSS_DIMMING_OFF].cmds[2].msg.tx_buf)[1]
= (panel->elvss_dimming_cmds.rbuf[0]);
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_ELVSS_DIMMING_OFF);
break;
case DISPPARAM_ELVSS_DIMMING_OFF:
pr_info("elvss dimming off\n");
((u8 *)panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_ELVSS_DIMMING_OFF].cmds[2].msg.tx_buf)[1]
= (panel->elvss_dimming_cmds.rbuf[0]) & 0x7F;
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_ELVSS_DIMMING_OFF);
@@ -5566,10 +5439,10 @@ int dsi_panel_disable(struct dsi_panel *panel)
panel->in_aod = false;
panel->fod_backlight_flag = false;
panel->dc_enable = false;
panel->dim_layer_replace_dc = false;
panel->power_mode = SDE_MODE_DPMS_OFF;
mutex_unlock(&panel->panel_lock);
pr_info("[SDE] %s: DSI_CMD_SET_OFF\n", __func__);
return rc;
}

View File

@@ -117,7 +117,6 @@ struct dsi_backlight_config {
u32 bl_scale_ad;
int en_gpio;
bool bl_remap_flag;
bool dcs_type_ss;
/* PWM params */
struct pwm_device *pwm_bl;
@@ -269,6 +268,8 @@ struct dsi_panel {
u32 dc_threshold;
bool dc_enable;
bool fod_dimlayer_bl_block;
bool dim_layer_replace_dc;
int power_mode;
enum dsi_panel_physical_type panel_type;

View File

@@ -25,7 +25,6 @@
#include "dsi_panel.h"
#include "sde_crtc.h"
#include "sde_rm.h"
#include "sde_trace.h"
#define BL_NODE_NAME_SIZE 32
@@ -86,7 +85,7 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
if ((bd->props.power != FB_BLANK_UNBLANK) ||
(bd->props.state & BL_CORE_FBBLANK) ||
(bd->props.state & BL_CORE_SUSPENDED))
(bd->props.state & BL_CORE_SUSPENDED))
brightness = 0;
c_conn = bl_get_data(bd);
@@ -94,12 +93,9 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
if (brightness > display->panel->bl_config.bl_max_level)
brightness = display->panel->bl_config.bl_max_level;
if (!display->panel->bl_config.bl_remap_flag) {
/* map UI brightness into driver backlight level with rounding */
bl_lvl = mult_frac(brightness, display->panel->bl_config.bl_max_level,
display->panel->bl_config.brightness_max_level);
} else
bl_lvl = brightness;
/* map UI brightness into driver backlight level with rounding */
bl_lvl = mult_frac(brightness, display->panel->bl_config.bl_max_level,
display->panel->bl_config.brightness_max_level);
if (!bl_lvl && brightness)
bl_lvl = 1;
@@ -647,7 +643,7 @@ static int dsi_display_write_panel(struct dsi_display *display,
if (cmds->last_command)
cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
len = ops->transfer(panel->host, &cmds->msg);//dsi_host_transfer,
len = ops->transfer(panel->host, &cmds->msg);
if (len < 0) {
rc = len;
pr_err("failed to set cmds, rc=%d\n", rc);
@@ -688,7 +684,7 @@ int sde_connector_update_hbm(struct sde_connector *c_conn)
connector = &c_conn->base;
if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI)
return rc;
return 0;
c_state = to_sde_connector_state(connector->state);
@@ -700,109 +696,101 @@ int sde_connector_update_hbm(struct sde_connector *c_conn)
return -EINVAL;
}
if (!dsi_display->panel->fod_dimlayer_enabled) {
return rc;
}
if (!dsi_display->panel->fod_dimlayer_enabled)
return 0;
if (!c_conn->encoder || !c_conn->encoder->crtc ||
!c_conn->encoder->crtc->state) {
return rc;
return 0;
}
dim_layer_status = sde_crtc_get_dim_layer_status(c_conn->encoder->crtc->state);
if (!dim_layer_status) {
if (dsi_display->panel->fod_dimlayer_hbm_enabled) {
mutex_lock(&dsi_display->panel->panel_lock);
/* FIXME: mutex_lock(&dsi_display->panel->panel_lock); */
/* Add delay for hbm off */
sde_encoder_wait_for_event(c_conn->encoder, MSM_ENC_VBLANK);
if ((dsi_display->drm_dev && dsi_display->drm_dev->doze_state == MSM_DRM_BLANK_LP1) ||
(dsi_display->drm_dev && dsi_display->drm_dev->doze_state == MSM_DRM_BLANK_LP2)) {
if (dsi_display->panel->last_bl_lvl > dsi_display->panel->doze_backlight_threshold) {
dsi_display->panel->hbm_enabled = false;
dsi_display->panel->fod_dimlayer_hbm_enabled = false;
dsi_display_write_panel(dsi_display, &dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DOZE_HBM]);
dsi_display_write_panel(dsi_display,
&dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DOZE_HBM]);
dsi_display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_HBM;
} else if (dsi_display->panel->last_bl_lvl < dsi_display->panel->doze_backlight_threshold
&& dsi_display->panel->last_bl_lvl > 0) {
dsi_display->panel->fod_dimlayer_hbm_enabled = false;
&& dsi_display->panel->last_bl_lvl > 0) {
dsi_display->panel->hbm_enabled = false;
pr_debug("set fod_dimlayer_hbm_enabled state at hbm fod off doze lbm on is [%d]", dsi_display->panel->fod_dimlayer_hbm_enabled);
dsi_display_write_panel(dsi_display, &dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DOZE_LBM]);
dsi_display->panel->fod_dimlayer_hbm_enabled = false;
dsi_display_write_panel(dsi_display,
&dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DOZE_LBM]);
dsi_display->drm_dev->doze_brightness = DOZE_BRIGHTNESS_LBM;
}
dsi_display->panel->in_aod = true;
dsi_display->panel->skip_dimmingon = STATE_DIM_BLOCK;
} else {
dsi_display->panel->fod_dimlayer_hbm_enabled = false;
dsi_display->panel->hbm_enabled = false;
/* disable FOD HBM */
if (dsi_display->panel->elvss_dimming_check_enable) {
rc = dsi_display_write_panel(dsi_display, &dsi_display->panel->hbm_fod_off);
} else {
rc = dsi_display_write_panel(dsi_display, &dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_HBM_FOD_OFF]);
}
/* Set flags to disable dimming and backlight */
dsi_display->panel->skip_dimmingon = STATE_DIM_RESTORE;
pr_debug("HBM fod off\n");
dsi_display->panel->hbm_enabled = false;
/* Disable FOD HBM */
dsi_display->panel->fod_dimlayer_hbm_enabled = false;
if (dsi_display->panel->elvss_dimming_check_enable)
rc = dsi_display_write_panel(dsi_display,
&dsi_display->panel->hbm_fod_off);
else
rc = dsi_display_write_panel(dsi_display,
&dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_HBM_FOD_OFF]);
sysfs_notify(&dsi_display->drm_conn->kdev->kobj, NULL, "dimlayer_hbm_enabled");
pr_debug("notify hbm off to displayfeature\n");
/* reset backlight level after HBM off*/
dsi_panel_set_backlight(dsi_display->panel, dsi_display->panel->last_bl_lvl);
/* notify brightness clone bl event */
sysfs_notify(&c_conn->bl_device->dev.kobj, NULL, "brightness_clone");
dsi_display->panel->dc_enable = true;
pr_debug("fod restore DC\n");
}
mutex_unlock(&dsi_display->panel->panel_lock);
if (rc) {
pr_err("failed to send DSI_CMD_HBM_OFF cmds, rc=%d\n", rc);
return rc;
if (dsi_display->panel->dim_layer_replace_dc) {
dsi_panel_set_backlight(dsi_display->panel,
c_conn->bl_device->props.brightness);
dsi_display->panel->dim_layer_replace_dc = false;
dsi_display->panel->dc_enable = true;
sysfs_notify(&c_conn->bl_device->dev.kobj, NULL,
"brightness_clone");
}
}
}
} else {
if (!dsi_display->panel->fod_dimlayer_hbm_enabled) {
mutex_lock(&dsi_display->panel->panel_lock);
/* FIXME: mutex_lock(&dsi_display->panel->panel_lock); */
/* Add delay for hbm on */
sde_encoder_wait_for_event(c_conn->encoder, MSM_ENC_VBLANK);
pr_debug("wait one frame for hbm on\n");
if (dsi_display->panel->last_bl_lvl || dsi_display->drm_dev->doze_state == MSM_DRM_BLANK_LP1
|| dsi_display->drm_dev->doze_state == MSM_DRM_BLANK_LP2) {
dsi_display->panel->fod_dimlayer_hbm_enabled = true;
if (dsi_display->panel->last_bl_lvl ||
dsi_display->drm_dev->doze_state == MSM_DRM_BLANK_LP1 ||
dsi_display->drm_dev->doze_state == MSM_DRM_BLANK_LP2) {
/* Set flags to disable dimming and backlight */
dsi_display->panel->skip_dimmingon = STATE_DIM_BLOCK;
dsi_display->panel->hbm_enabled = true;
pr_debug("HBM fod on\n");
/* enable FOD HBM */
if (dsi_display->panel->elvss_dimming_check_enable) {
rc = dsi_display_write_panel(dsi_display, &dsi_display->panel->hbm_fod_on);
} else {
rc = dsi_display_write_panel(dsi_display, &dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_HBM_FOD_ON]);
}
/* Enable FOD HBM */
dsi_display->panel->fod_dimlayer_hbm_enabled = true;
if (dsi_display->panel->elvss_dimming_check_enable)
rc = dsi_display_write_panel(dsi_display,
&dsi_display->panel->hbm_fod_on);
else
rc = dsi_display_write_panel(dsi_display,
&dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_HBM_FOD_ON]);
sysfs_notify(&dsi_display->drm_conn->kdev->kobj, NULL, "dimlayer_hbm_enabled");
pr_debug("notify hbm on to displayfeature\n");
}
/* reset backlight level after HBM on*/
dsi_panel_set_backlight(dsi_display->panel, dsi_display->panel->last_bl_lvl);
if (dsi_display->panel->fod_dimlayer_bl_block) {
dsi_display->panel->fod_dimlayer_bl_block = false;
dsi_panel_set_backlight(dsi_display->panel,
dsi_display->panel->last_bl_lvl);
}
if (dsi_display->panel->dc_enable) {
dsi_display->panel->dim_layer_replace_dc = true;
dsi_display->panel->dc_enable = false;
pr_debug("fod set CRC OFF\n");
dsi_display_write_panel(dsi_display, &dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_CRC_OFF]);
}
/* force disable CRC */
pr_debug("fod set CRC OFF\n");
dsi_display_write_panel(dsi_display, &dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_CRC_OFF]);
mutex_unlock(&dsi_display->panel->panel_lock);
if (rc) {
pr_err("failed to send DSI_CMD_HBM_ON cmds, rc=%d\n", rc);
return rc;
dsi_display_write_panel(dsi_display,
&dsi_display->panel->cur_mode->priv_info->cmd_sets[DSI_CMD_SET_DISP_CRC_OFF]);
}
}
}
pr_debug("dim_layer_status:%d fod_dimlayer_hbm_enabled:%d\n", dim_layer_status, dsi_display->panel->fod_dimlayer_hbm_enabled);
return rc;
}
@@ -1358,7 +1346,7 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
idx = msm_property_index(&c_conn->property_info, property);
switch (idx) {
case CONNECTOR_PROP_LP:
if(connector->dev)
if (connector->dev)
connector->dev->doze_state = val;
break;
case CONNECTOR_PROP_OUT_FB:

View File

@@ -580,8 +580,10 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
pm_runtime_get_noresume(dev->dev);
} else {
ret = pm_runtime_get_sync(dev->dev);
if (ret < 0 && ret != -EACCES)
if (ret < 0 && ret != -EACCES) {
pm_runtime_put_autosuspend(dev->dev);
return conn_status;
}
}
nv_encoder = nouveau_connector_ddc_detect(connector);

View File

@@ -184,8 +184,10 @@ nouveau_fbcon_open(struct fb_info *info, int user)
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
int ret = pm_runtime_get_sync(drm->dev->dev);
if (ret < 0 && ret != -EACCES)
if (ret < 0 && ret != -EACCES) {
pm_runtime_put(drm->dev->dev);
return ret;
}
return 0;
}

View File

@@ -895,8 +895,10 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
if (encoder) {
@@ -1041,8 +1043,10 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
encoder = radeon_best_single_encoder(connector);
@@ -1179,8 +1183,10 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
encoder = radeon_best_single_encoder(connector);
@@ -1263,8 +1269,10 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
if (radeon_connector->detected_hpd_without_ddc) {
@@ -1704,8 +1712,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
if (!drm_kms_helper_is_poll_worker()) {
r = pm_runtime_get_sync(connector->dev->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(connector->dev->dev);
return connector_status_disconnected;
}
}
if (!force && radeon_check_hpd_status_unchanged(connector)) {

View File

@@ -406,6 +406,19 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
dev_err(&client->dev, "failed to change power setting.\n");
set_pwr_exit:
/*
* The HID over I2C specification states that if a DEVICE needs time
* after the PWR_ON request, it should utilise CLOCK stretching.
* However, it has been observered that the Windows driver provides a
* 1ms sleep between the PWR_ON and RESET requests.
* According to Goodix Windows even waits 60 ms after (other?)
* PWR_ON requests. Testing has confirmed that several devices
* will not work properly without a delay after a PWR_ON request.
*/
if (!ret && power_state == I2C_HID_PWR_ON)
msleep(60);
return ret;
}
@@ -427,15 +440,6 @@ static int i2c_hid_hwreset(struct i2c_client *client)
if (ret)
goto out_unlock;
/*
* The HID over I2C specification states that if a DEVICE needs time
* after the PWR_ON request, it should utilise CLOCK stretching.
* However, it has been observered that the Windows driver provides a
* 1ms sleep between the PWR_ON and RESET requests and that some devices
* rely on this.
*/
usleep_range(1000, 5000);
i2c_hid_dbg(ihid, "resetting...\n");
ret = i2c_hid_command(client, &hid_reset_cmd, NULL, 0);

View File

@@ -532,12 +532,16 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
switch (cmd) {
case HIDIOCGUSAGE:
if (uref->usage_index >= field->report_count)
goto inval;
uref->value = field->value[uref->usage_index];
if (copy_to_user(user_arg, uref, sizeof(*uref)))
goto fault;
goto goodreturn;
case HIDIOCSUSAGE:
if (uref->usage_index >= field->report_count)
goto inval;
field->value[uref->usage_index] = uref->value;
goto goodreturn;

View File

@@ -545,6 +545,7 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
/* master sent stop */
if (ssr_filtered & SSR) {
i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value);
rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */
rcar_i2c_write(priv, ICSIER, SAR);
rcar_i2c_write(priv, ICSSR, ~SSR & 0xff);
}

View File

@@ -42,4 +42,9 @@ config TOUCHSCREEN_GOODIX_GTX8_TOOLS
To compile this driver as a module, choose M here.
config TOUCHSCREEN_GOODIX_GTX8_GAMEMODE
bool "Goodix game mode support"
default y
help
Say Y here to enable game mode.
endif

View File

@@ -10,7 +10,7 @@ int goodix_start_cfg_bin(struct goodix_ts_core *ts_core)
{
struct task_struct *cfg_bin_thrd;
/* create and run update thread */
ts_err("enter::%s\n",__func__);
ts_err("enter::%s\n", __func__);
cfg_bin_thrd = kthread_run(goodix_cfg_bin_proc, ts_core, "goodix-parse_cfg_bin");
if (IS_ERR_OR_NULL(cfg_bin_thrd)) {
ts_err("Failed to create update thread:%ld", PTR_ERR(cfg_bin_thrd));
@@ -24,6 +24,7 @@ int goodix_parse_cfg_bin(struct goodix_cfg_bin *cfg_bin)
u8 checksum;
int i, r;
u16 offset1, offset2;
if (!cfg_bin->bin_data || cfg_bin->bin_data_len == 0) {
ts_err("NO cfg_bin data, cfg_bin data length:%d", cfg_bin->bin_data_len);
r = -EINVAL;
@@ -50,9 +51,9 @@ int goodix_parse_cfg_bin(struct goodix_cfg_bin *cfg_bin)
/*check cfg_bin valid*/
checksum = 0;
for (i = TS_BIN_VERSION_START_INDEX; i < cfg_bin->bin_data_len; i++) {
for (i = TS_BIN_VERSION_START_INDEX; i < cfg_bin->bin_data_len; i++)
checksum += cfg_bin->bin_data[i];
}
if (checksum != cfg_bin->head.checksum) {
ts_err("cfg_bin checksum ERROR, checksum in cfg_bin:0x%02x, checksum caculate:0x%02x",
cfg_bin->head.checksum, checksum);
@@ -63,7 +64,6 @@ int goodix_parse_cfg_bin(struct goodix_cfg_bin *cfg_bin)
/*allocate memory for cfg packages*/
cfg_bin->cfg_pkgs = kzalloc(sizeof(struct goodix_cfg_package) * cfg_bin->head.pkg_num, GFP_KERNEL);
if (!cfg_bin->cfg_pkgs) {
ts_err("cfg_pkgs, allocate memory ERROR");
r = -ENOMEM;
goto exit;
}
@@ -147,8 +147,8 @@ int goodix_cfg_bin_proc(void *data)
int r;
struct goodix_cfg_bin *cfg_bin = kzalloc(sizeof(struct goodix_cfg_bin), GFP_KERNEL);
if (!cfg_bin) {
ts_err("Failed to alloc memory for cfg_bin");
r = -ENOMEM;
goto exit;
}
@@ -222,7 +222,8 @@ int goodix_cfg_bin_proc(void *data)
core_data->cfg_group_parsed = true;
/* inform the external module manager that
* touch core layer is ready now */
* touch core layer is ready now
*/
core_data->fod_status = 1;
goodix_modules.core_data = core_data;
goodix_modules.core_exit = false;
@@ -263,6 +264,7 @@ int goodix_get_reg_and_cfg(struct goodix_ts_device *ts_dev, struct goodix_cfg_bi
u8 temp_fw_mask[TS_CFG_BLOCK_FW_MASK_LEN] = {0x00};
u8 temp_pid[TS_CFG_BLOCK_PID_LEN] = {0x00};
int r = -EINVAL;
normal_pkg = NULL;
high_sense_pkg = NULL;
@@ -343,10 +345,10 @@ int goodix_get_reg_and_cfg(struct goodix_ts_device *ts_dev, struct goodix_cfg_bi
ts_err("read pid FAILED, I2C ERROR, pkg: %d, pid reg:0x%02x", i, addr);
goto exit;
} else if (strncmp(temp_pid, cfg_bin->cfg_pkgs[i].cnst_info.hw_pid, read_len)) {
ts_err("pkg:%d, pid contrast FAILED, reg:0x%02x", i, addr);
ts_err("pid from i2c:%s, pid of cfg bin:%s", temp_pid,
cfg_bin->cfg_pkgs[i].cnst_info.hw_pid);
continue;
ts_err("pkg:%d, pid contrast FAILED, reg:0x%02x", i, addr);
ts_err("pid from i2c:%s, pid of cfg bin:%s", temp_pid,
cfg_bin->cfg_pkgs[i].cnst_info.hw_pid);
continue;
}
/*contrast success, cfg_type*/
@@ -406,10 +408,9 @@ int goodix_get_reg_and_cfg(struct goodix_ts_device *ts_dev, struct goodix_cfg_bi
if (!ts_dev->normal_cfg) {
ts_dev->normal_cfg = devm_kzalloc(ts_dev->dev,
sizeof(*ts_dev->normal_cfg), GFP_KERNEL);
if (!ts_dev->normal_cfg) {
ts_err("Failed to alloc memory for normal cfg");
if (!ts_dev->normal_cfg)
return -ENOMEM;
}
mutex_init(&ts_dev->normal_cfg->lock);
}
@@ -424,10 +425,9 @@ int goodix_get_reg_and_cfg(struct goodix_ts_device *ts_dev, struct goodix_cfg_bi
if (!ts_dev->highsense_cfg) {
ts_dev->highsense_cfg = devm_kzalloc(ts_dev->dev,
sizeof(*ts_dev->highsense_cfg), GFP_KERNEL);
if (!ts_dev->highsense_cfg) {
ts_err("Failed to alloc memory for high sense cfg");
if (!ts_dev->highsense_cfg)
return -ENOMEM;
}
mutex_init(&ts_dev->highsense_cfg->lock);
}
@@ -492,10 +492,9 @@ int goodix_read_cfg_bin(struct device *dev, struct goodix_cfg_bin *cfg_bin)
cfg_bin->bin_data_len = firmware->size;
/*allocate memory for cfg_bin->bin_data*/
cfg_bin->bin_data = kzalloc(cfg_bin->bin_data_len, GFP_KERNEL);
if (!cfg_bin->bin_data) {
ts_err("Allocate memory for cfg_bin->bin_data FAILED");
if (!cfg_bin->bin_data)
r = -ENOMEM;
}
memcpy(cfg_bin->bin_data, firmware->data, cfg_bin->bin_data_len);
r = 0;
exit:
@@ -520,10 +519,9 @@ int goodix_read_cfg_bin_from_dts(struct device_node *node, struct goodix_cfg_bin
cfg_bin->bin_data_len = len;
/*allocate memory for cfg_bin->bin_data*/
cfg_bin->bin_data = kzalloc(cfg_bin->bin_data_len, GFP_KERNEL);
if (!cfg_bin->bin_data) {
ts_err("Allocate memory for cfg_bin->bin_data FAILED");
if (!cfg_bin->bin_data)
return -ENOMEM;
}
memcpy(cfg_bin->bin_data, prop->value, cfg_bin->bin_data_len);
return 0;
}

View File

@@ -62,8 +62,9 @@
#define TS_CHECK_ISP_STATE_RETRY_TIMES 200
#define TS_READ_FLASH_STATE_RETRY_TIMES 200
/*0: Header update
*1: request firmware update*/
/* 0: Header update
* 1: request firmware update
*/
atomic_t fw_update_mode = ATOMIC_INIT(1);
/**
@@ -202,7 +203,8 @@ static int goodix_parse_firmware(struct firmware_data *fw_data)
}
/* calculate checksum, note: sum of bytes, but check
* by u16 checksum */
* by u16 checksum
*/
for (i = 6, checksum = 0; i < firmware->size; i++)
checksum += firmware->data[i];
@@ -277,22 +279,23 @@ static int goodix_check_update(struct goodix_ts_device *dev,
/* read version from chip, if we got invalid
* firmware version, maybe fimware in flash is
* incorrect, so we need to update firmware */
* incorrect, so we need to update firmware
*/
r = dev->hw_ops->read_version(dev, &fw_ver);
if (r == -EBUS)
return r;
if (fw_ver.valid) {
ts_info("pid_len=%d\n",dev->reg.pid_len);
ts_info("tp.pid=%s fw.pid=%s\n",fw_ver.pid,fw_info->fw_pid);
ts_info("pid_len=%d\n", dev->reg.pid_len);
ts_info("tp.pid=%s fw.pid=%s\n", fw_ver.pid, fw_info->fw_pid);
if (memcmp(fw_ver.pid, fw_info->fw_pid, dev->reg.pid_len)) {
ts_err("tp.pid=0x%s fw.pid=0x%hhn\n",fw_ver.pid,fw_info->fw_pid);
ts_err("tp.pid=0x%s fw.pid=0x%hhn\n", fw_ver.pid, fw_info->fw_pid);
ts_err("Product ID is not match");
return -EPERM;
}
ts_info("vid_len=%d\n",dev->reg.vid_len);
ts_info("Touchpanel VID:0x%02x 0x%02x 0x%02x 0x%02x",fw_ver.vid[0], fw_ver.vid[1], fw_ver.vid[2], fw_ver.vid[3]);
ts_info("vid_len=%d\n", dev->reg.vid_len);
ts_info("Touchpanel VID:0x%02x 0x%02x 0x%02x 0x%02x", fw_ver.vid[0], fw_ver.vid[1], fw_ver.vid[2], fw_ver.vid[3]);
ts_info("Fimware VID:0x%02X 0x%02x 0x%02x 0x%02x", fw_info->fw_vid[0], fw_info->fw_vid[1], fw_info->fw_vid[2], fw_info->fw_vid[3]);
res = memcmp(fw_ver.vid, fw_info->fw_vid, dev->reg.vid_len);
if (res == 0) {
@@ -325,13 +328,10 @@ static int goodix_reg_write_confirm(struct goodix_ts_device *dev,
if (len > sizeof(cfm_buf)) {
cfm = kzalloc(len, GFP_KERNEL);
if (!cfm) {
ts_err("Mem alloc failed");
if (!cfm)
return -ENOMEM;
}
} else {
} else
cfm = &cfm_buf[0];
}
for (i = 0; i < GOODIX_BUS_RETRY_TIMES; i++) {
r = dev->hw_ops->write_trans(dev, addr, data, len);
@@ -569,6 +569,7 @@ static int goodix_format_fw_packet(u8 *pkt, u32 flash_addr,
u16 len, const u8 *data)
{
u16 checksum;
if (!pkt || !data)
return -EINVAL;
@@ -754,7 +755,8 @@ static int goodix_flash_firmware(struct goodix_ts_device *dev,
int i, r = 0, fw_num, prog_step;
/* start from subsystem 1,
* subsystem 0 is the ISP program */
* subsystem 0 is the ISP program
*/
fw_ctrl = container_of(fw_data, struct fw_update_ctrl, fw_data);
fw_info = &fw_data->fw_info;
fw_num = fw_info->subsys_num;
@@ -951,7 +953,7 @@ static int goodix_fw_update_thread(void *data)
static DEFINE_MUTEX(fwu_lock);
int r;
ts_err("%s:start\n",__func__);
ts_err("%s:start\n", __func__);
if (!fwu_ctrl) {
ts_err("Invaid thread params");
goodix_unregister_ext_module(&goodix_fwu_module);
@@ -1037,7 +1039,8 @@ static ssize_t goodix_sysfs_update_en_store(
const char *buf, size_t count)
{
int val = 0, r;
r = sscanf(buf, "%d", &val);
r = kstrtoint(buf, 0, &val);
if (r < 0)
return r;
if (r) {
@@ -1053,6 +1056,7 @@ static ssize_t goodix_sysfs_update_progress_show(
char *buf)
{
struct fw_update_ctrl *fw_ctrl = module->priv_data;
return scnprintf(buf, PAGE_SIZE, "%d\n", fw_ctrl->progress);
}
@@ -1138,10 +1142,8 @@ static ssize_t goodix_sysfs_fwsize_store(struct goodix_ext_module *module,
}
fw = vmalloc(sizeof(*fw) + size);
if (fw == NULL) {
ts_err("Failed to alloc memory,size:%zu", size + sizeof(*fw));
if (fw == NULL)
return -ENOMEM;
}
memset(fw, 0x00, sizeof(*fw) + size);
data = (u8 **)&fw->data;
@@ -1186,7 +1188,7 @@ static ssize_t goodix_sysfs_force_update_store(
struct fw_update_ctrl *fw_ctrl = module->priv_data;
int val = 0, r;
r = sscanf(buf, "%d", &val);
r = kstrtoint(buf, 0, &val);
if (r < 0)
return r;
if (r)
@@ -1197,12 +1199,12 @@ static ssize_t goodix_sysfs_force_update_store(
}
static struct goodix_ext_attribute goodix_fwu_attrs[] = {
__EXTMOD_ATTR(update_en, S_IWUGO, NULL, goodix_sysfs_update_en_store),
__EXTMOD_ATTR(progress, S_IRUGO, goodix_sysfs_update_progress_show, NULL),
__EXTMOD_ATTR(result, S_IRUGO, goodix_sysfs_update_result_show, NULL),
__EXTMOD_ATTR(fwversion, S_IRUGO, goodix_sysfs_update_fwversion_show, NULL),
__EXTMOD_ATTR(fwsize, S_IRUGO | S_IWUGO, goodix_sysfs_fwsize_show, goodix_sysfs_fwsize_store),
__EXTMOD_ATTR(force_update, S_IWUGO, NULL, goodix_sysfs_force_update_store),
__EXTMOD_ATTR(update_en, 0222, NULL, goodix_sysfs_update_en_store),
__EXTMOD_ATTR(progress, 0444, goodix_sysfs_update_progress_show, NULL),
__EXTMOD_ATTR(result, 0444, goodix_sysfs_update_result_show, NULL),
__EXTMOD_ATTR(fwversion, 0444, goodix_sysfs_update_fwversion_show, NULL),
__EXTMOD_ATTR(fwsize, 0666, goodix_sysfs_fwsize_show, goodix_sysfs_fwsize_store),
__EXTMOD_ATTR(force_update, 0222, NULL, goodix_sysfs_force_update_store),
};
static int goodix_syfs_init(struct goodix_ts_core *core_data,
@@ -1230,7 +1232,7 @@ static int goodix_syfs_init(struct goodix_ts_core *core_data,
}
fw_ctrl->attr_fwimage.attr.name = "fwimage";
fw_ctrl->attr_fwimage.attr.mode = S_IRUGO | S_IWUGO;
fw_ctrl->attr_fwimage.attr.mode = 0666;
fw_ctrl->attr_fwimage.size = 0;
fw_ctrl->attr_fwimage.write = goodix_sysfs_fwimage_store;
ret = sysfs_create_bin_file(&module->kobj, &fw_ctrl->attr_fwimage);
@@ -1252,10 +1254,8 @@ static int goodix_fw_update_init(struct goodix_ts_core *core_data,
if (!module->priv_data) {
module->priv_data = kzalloc(sizeof(struct fw_update_ctrl), GFP_KERNEL);
if (!module->priv_data) {
ts_err("Failed to alloc memory for fwu_ctrl");
if (!module->priv_data)
return -ENOMEM;
}
}
fwu_ctrl = module->priv_data;
fwu_ctrl->ts_dev = core_data->ts_dev;
@@ -1266,10 +1266,10 @@ static int goodix_fw_update_init(struct goodix_ts_core *core_data,
fwu_ctrl->core_data = core_data;
/* find a valid firmware image name */
if (ts_bdata && ts_bdata->fw_name){
if (ts_bdata && ts_bdata->fw_name) {
strlcpy(fwu_ctrl->fw_name, ts_bdata->fw_name, sizeof(fwu_ctrl->fw_name));
ts_info("find goodix firmware:%s\n",ts_bdata->fw_name);
}else{
ts_info("find goodix firmware:%s\n", ts_bdata->fw_name);
} else{
strlcpy(fwu_ctrl->fw_name, TS_DEFAULT_FIRMWARE, sizeof(fwu_ctrl->fw_name));
ts_info("can't find goodix firmware,use default name\n");
}
@@ -1309,6 +1309,7 @@ static int goodix_fw_before_resume(struct goodix_ts_core *core_data,
struct goodix_ext_module *module)
{
struct fw_update_ctrl *fwu_ctrl = module->priv_data;
return fwu_ctrl->allow_resume ?
EVT_HANDLED : EVT_CANCEL_RESUME;
}
@@ -1323,6 +1324,7 @@ static int goodix_fw_irq_event(struct goodix_ts_core *core_data,
struct goodix_ext_module *module)
{
struct fw_update_ctrl *fwu_ctrl = module->priv_data;
return fwu_ctrl->allow_irq ?
EVT_HANDLED : EVT_CANCEL_IRQEVT;
}
@@ -1331,6 +1333,7 @@ static int goodix_fw_before_reset(struct goodix_ts_core *core_data,
struct goodix_ext_module *module)
{
struct fw_update_ctrl *fwu_ctrl = module->priv_data;
return fwu_ctrl->allow_reset ?
EVT_HANDLED : EVT_CANCEL_RESET;
}

View File

@@ -82,7 +82,7 @@ static void __do_register_ext_module(struct work_struct *work)
struct goodix_ext_module *ext_module;
struct list_head *insert_point = &goodix_modules.head;
ts_info("__do_register_ext_module IN, goodix_modules.core_exit:%d", goodix_modules.core_exit);
ts_info("%s IN, goodix_modules.core_exit:%d", __func__, goodix_modules.core_exit);
/* waitting for core layer */
if (!wait_for_completion_timeout(&goodix_modules.core_comp, 25 * HZ)) {
@@ -116,13 +116,13 @@ static void __do_register_ext_module(struct work_struct *work)
list_for_each_entry(ext_module, &goodix_modules.head, list) {
/* small value of priority have
* higher priority level*/
* higher priority level
*/
if (ext_module->priority >= module->priority) {
insert_point = &ext_module->list;
break;
}
} /* else module will be inserted
to goodix_modules->head */
}
}
if (module->funcs && module->funcs->init) {
@@ -168,10 +168,10 @@ int goodix_register_ext_module(struct goodix_ext_module *module)
return -EFAULT;
}
*/
ts_info("goodix_register_ext_module IN");
ts_info("%s IN", __func__);
INIT_WORK(&module->work, __do_register_ext_module);
schedule_work(&module->work);
ts_info("goodix_register_ext_module OUT");
ts_info("%s OUT", __func__);
return 0;
}
EXPORT_SYMBOL_GPL(goodix_register_ext_module);
@@ -187,6 +187,7 @@ int goodix_unregister_ext_module(struct goodix_ext_module *module)
{
struct goodix_ext_module *ext_module;
bool found = false;
if (!module)
return -EINVAL;
if (!goodix_modules.initilized)
@@ -306,6 +307,7 @@ EXPORT_SYMBOL_GPL(goodix_msg_printf);
static int goodix_debugfs_init(void)
{
struct dentry *r_b;
goodix_dbg.buf.size = PAGE_SIZE;
goodix_dbg.pos = 0;
goodix_dbg.buf.data = kzalloc(goodix_dbg.buf.size, GFP_KERNEL);
@@ -439,6 +441,7 @@ static ssize_t goodix_ts_reset_store(struct device *dev,
return -EINVAL;
if (en != 1)
return -EINVAL;
if (ts_dev->hw_ops->reset)
ts_dev->hw_ops->reset(ts_dev);
return count;
@@ -452,6 +455,7 @@ static ssize_t goodix_ts_read_cfg_show(struct device *dev,
struct goodix_ts_device *ts_dev = core_data->ts_dev;
int ret, i, offset;
char *cfg_buf;
cfg_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
disable_irq(core_data->irq);
@@ -515,8 +519,7 @@ static int goodix_ts_convert_0x_data(const u8 *buf, int buf_size,
continue;
if (temp_index >= m_size) {
ts_err("exchange cfg data error, overflow,"
"temp_index:%d,m_size:%d\n",
ts_err("exchange cfg data error, overflow,temp_index:%d,m_size:%d\n",
temp_index, m_size);
return -EINVAL;
}
@@ -543,10 +546,9 @@ static ssize_t goodix_ts_send_cfg_store(struct device *dev,
const struct firmware *cfg_img;
struct goodix_ts_config *config = NULL;
ts_err("%s::enter\n",__func__);
ts_err("%s::enter\n", __func__);
if (sscanf(buf, "%d", &en) != 1)
return -EINVAL;
if (en != 1)
return -EINVAL;
@@ -562,10 +564,8 @@ static ssize_t goodix_ts_send_cfg_store(struct device *dev,
ts_info("cfg file [%s] is ready", GOODIX_DEFAULT_CFG_NAME);
config = kzalloc(sizeof(*config), GFP_KERNEL);
if (config == NULL) {
ts_err("Memory allco err");
if (config == NULL)
goto exit;
}
/*parse cfg data*/
if (goodix_ts_convert_0x_data(cfg_img->data, cfg_img->size,
@@ -649,15 +649,207 @@ static ssize_t goodix_ts_irq_info_store(struct device *dev,
return count;
}
static DEVICE_ATTR(extmod_info, S_IRUGO, goodix_ts_extmod_show, NULL);
static DEVICE_ATTR(driver_info, S_IRUGO, goodix_ts_driver_info_show, NULL);
static DEVICE_ATTR(chip_info, S_IRUGO, goodix_ts_chip_info_show, NULL);
static DEVICE_ATTR(config_data, S_IRUGO, goodix_ts_config_data_show, NULL);
static DEVICE_ATTR(reset, S_IWUSR | S_IWGRP, NULL, goodix_ts_reset_store);
static DEVICE_ATTR(send_cfg, S_IWUSR | S_IWGRP, NULL, goodix_ts_send_cfg_store);
static DEVICE_ATTR(read_cfg, S_IRUGO, goodix_ts_read_cfg_show, NULL);
static DEVICE_ATTR(irq_info, S_IRUGO | S_IWUSR | S_IWGRP,
#ifdef CONFIG_TOUCHSCREEN_GOODIX_GTX8_GAMEMODE
static int gtp_set_cur_value(int gtp_mode, int gtp_value)
{
u8 state_data[3] = { 0 };
u8 goodix_game_value = 0;
u8 temp_value = 0;
int ret = 0;
int i = 0;
struct goodix_ts_device *dev = goodix_core_data->ts_dev;
if (gtp_mode >= Touch_Mode_NUM && gtp_mode < 0)
return -EINVAL;
goodix_core_data->touch_mode[gtp_mode][SET_CUR_VALUE] = gtp_value;
if (goodix_core_data->touch_mode[gtp_mode][SET_CUR_VALUE] >
goodix_core_data->touch_mode[gtp_mode][GET_MAX_VALUE]) {
goodix_core_data->touch_mode[gtp_mode][SET_CUR_VALUE] =
goodix_core_data->touch_mode[gtp_mode][GET_MAX_VALUE];
} else if (goodix_core_data->touch_mode[gtp_mode][SET_CUR_VALUE] <
goodix_core_data->touch_mode[gtp_mode][GET_MIN_VALUE]) {
goodix_core_data->touch_mode[gtp_mode][SET_CUR_VALUE] =
goodix_core_data->touch_mode[gtp_mode][GET_MIN_VALUE];
}
ts_info("GAME -> MODE:%d, VALUE:%d", gtp_mode, gtp_value);
if (goodix_core_data->touch_mode[Touch_Game_Mode][SET_CUR_VALUE] == 0) {
ts_info("GAME -> exit touch game mode");
state_data[0] = GTP_EXIT_GAME_CMD;
state_data[1] = 0x00;
state_data[2] = 0xF1;
ret = goodix_i2c_write(dev, GTP_GAME_CMD_ADD, state_data, 3);
if (ret < 0)
ts_info("GAME -> exit game mode fail");
goodix_game_value = 0;
goodix_core_data->touch_mode[gtp_mode][GET_CUR_VALUE] = goodix_core_data->touch_mode[gtp_mode][GET_DEF_VALUE];
return ret;
} else {
/* Temp Workaround */
goodix_core_data->touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE] = 1;
for (i = 0; i < Touch_Mode_NUM; i++) {
switch (i) {
case Touch_Game_Mode:
break;
case Touch_UP_THRESHOLD:
temp_value =
goodix_core_data->touch_mode[Touch_UP_THRESHOLD][SET_CUR_VALUE];
goodix_game_value &= 0xFC;
goodix_game_value |= temp_value;
break;
case Touch_Tolerance:
temp_value =
goodix_core_data->touch_mode[Touch_Tolerance][SET_CUR_VALUE];
temp_value = 3 - temp_value;
goodix_game_value &= 0xF3;
goodix_game_value |= (temp_value << 2);
break;
case Touch_Edge_Filter:
temp_value =
goodix_core_data->touch_mode[Touch_Edge_Filter][SET_CUR_VALUE];
goodix_game_value &= 0xCF;
goodix_game_value |= (temp_value << 4);
break;
case Touch_Panel_Orientation:
/* 0, 1, 2, 3 = 0, 90, 180, 270 */
temp_value =
goodix_core_data->touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE];
if (temp_value == 3)
temp_value = 2;
else if (temp_value == 2)
temp_value = 3;
goodix_game_value &= 0x3F;
goodix_game_value |= (temp_value << 6);
break;
default:
/* Don't support */
break;
};
}
goodix_core_data->touch_mode[gtp_mode][GET_CUR_VALUE] =
goodix_core_data->touch_mode[gtp_mode][SET_CUR_VALUE];
state_data[0] = GTP_GAME_CMD;
state_data[1] = goodix_game_value;
state_data[2] = 0xFF & (0 - state_data[0] - state_data[1]);
ts_info("GAME -> MODE:%d, VALUE:%d --> cmd1:0x%x, cmd2:0x%x, cmd3:0x%x",
gtp_mode, gtp_value, state_data[0], state_data[1], state_data[2]);
ret = goodix_i2c_write(dev, GTP_GAME_CMD_ADD, state_data, 5);
if (ret < 0)
ts_info("GAME -> change game mode fail");
}
return ret;
}
static void gtp_init_touchmode_data(void)
{
int i;
/* Touch Game Mode Switch */
goodix_core_data->touch_mode[Touch_Game_Mode][GET_DEF_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Game_Mode][GET_MAX_VALUE] = 1;
goodix_core_data->touch_mode[Touch_Game_Mode][GET_MIN_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Game_Mode][SET_CUR_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Game_Mode][GET_CUR_VALUE] = 0;
/* Finger hysteresis */
goodix_core_data->touch_mode[Touch_UP_THRESHOLD][GET_MAX_VALUE] = 3;
goodix_core_data->touch_mode[Touch_UP_THRESHOLD][GET_MIN_VALUE] = 0;
goodix_core_data->touch_mode[Touch_UP_THRESHOLD][GET_DEF_VALUE] = 0;
goodix_core_data->touch_mode[Touch_UP_THRESHOLD][SET_CUR_VALUE] = 0;
goodix_core_data->touch_mode[Touch_UP_THRESHOLD][GET_CUR_VALUE] = 0;
/* Tolerance */
goodix_core_data->touch_mode[Touch_Tolerance][GET_MAX_VALUE] = 3;
goodix_core_data->touch_mode[Touch_Tolerance][GET_MIN_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Tolerance][GET_DEF_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Tolerance][SET_CUR_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Tolerance][GET_CUR_VALUE] = 0;
/* Edge filter */
goodix_core_data->touch_mode[Touch_Edge_Filter][GET_MAX_VALUE] = 3;
goodix_core_data->touch_mode[Touch_Edge_Filter][GET_MIN_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Edge_Filter][GET_DEF_VALUE] = 1;
goodix_core_data->touch_mode[Touch_Edge_Filter][SET_CUR_VALUE] = 1;
goodix_core_data->touch_mode[Touch_Edge_Filter][GET_CUR_VALUE] = 1;
/* Orientation */
goodix_core_data->touch_mode[Touch_Panel_Orientation][GET_MAX_VALUE] = 3;
goodix_core_data->touch_mode[Touch_Panel_Orientation][GET_MIN_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Panel_Orientation][GET_DEF_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Panel_Orientation][SET_CUR_VALUE] = 0;
goodix_core_data->touch_mode[Touch_Panel_Orientation][GET_CUR_VALUE] = 0;
for (i = 0; i < Touch_Mode_NUM; i++) {
ts_info("GAME --> mode:%d, set cur:%d, get cur:%d, def:%d, min:%d, max:%d\n",
i,
goodix_core_data->touch_mode[i][SET_CUR_VALUE],
goodix_core_data->touch_mode[i][GET_CUR_VALUE],
goodix_core_data->touch_mode[i][GET_DEF_VALUE],
goodix_core_data->touch_mode[i][GET_MIN_VALUE],
goodix_core_data->touch_mode[i][GET_MAX_VALUE]);
}
return;
}
static ssize_t goodix_ts_game_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct goodix_ts_core *core_data = dev_get_drvdata(dev);
if (core_data == NULL)
return snprintf(buf, PAGE_SIZE, "error\n");
return snprintf(buf, PAGE_SIZE, "%d %d %d %d\n",
goodix_core_data->touch_mode[Touch_Game_Mode][GET_CUR_VALUE],
goodix_core_data->touch_mode[Touch_Tolerance][GET_CUR_VALUE],
goodix_core_data->touch_mode[Touch_UP_THRESHOLD][GET_CUR_VALUE],
goodix_core_data->touch_mode[Touch_Edge_Filter][GET_CUR_VALUE]);
}
static ssize_t goodix_ts_game_mode_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int rc, i;
unsigned int u[Touch_Mode_NUM] = { 0 };
ts_info("GAME -> buf : %s, len : %d\n", buf, count);
rc = sscanf(buf, "%d %d %d %d\n", &u[Touch_Game_Mode], &u[Touch_Tolerance], &u[Touch_UP_THRESHOLD], &u[Touch_Edge_Filter]);
if (rc != 4) {
ts_info("GAME -> Invalid Format!");
return -EINVAL;
}
for (i = 0; i < Touch_Mode_NUM; i++)
gtp_set_cur_value(i, u[i]);
return count;
}
#endif
static DEVICE_ATTR(extmod_info, 0444, goodix_ts_extmod_show, NULL);
static DEVICE_ATTR(driver_info, 0444, goodix_ts_driver_info_show, NULL);
static DEVICE_ATTR(chip_info, 0444, goodix_ts_chip_info_show, NULL);
static DEVICE_ATTR(config_data, 0444, goodix_ts_config_data_show, NULL);
static DEVICE_ATTR(reset, 0220, NULL, goodix_ts_reset_store);
static DEVICE_ATTR(send_cfg, 0220, NULL, goodix_ts_send_cfg_store);
static DEVICE_ATTR(read_cfg, 0444, goodix_ts_read_cfg_show, NULL);
static DEVICE_ATTR(irq_info, 0664,
goodix_ts_irq_info_show, goodix_ts_irq_info_store);
#ifdef CONFIG_TOUCHSCREEN_GOODIX_GTX8_GAMEMODE
static DEVICE_ATTR(game_mode, 0664,
goodix_ts_game_mode_show, goodix_ts_game_mode_store);
#endif
static struct attribute *sysfs_attrs[] = {
&dev_attr_extmod_info.attr,
@@ -668,6 +860,9 @@ static struct attribute *sysfs_attrs[] = {
&dev_attr_send_cfg.attr,
&dev_attr_read_cfg.attr,
&dev_attr_irq_info.attr,
#ifdef CONFIG_TOUCHSCREEN_GOODIX_GTX8_GAMEMODE
&dev_attr_game_mode.attr,
#endif
NULL,
};
@@ -724,6 +919,7 @@ static void release_all_touches(struct goodix_ts_core *core_data)
unsigned int type = MT_TOOL_FINGER;
struct goodix_ts_device *ts_dev = core_data->ts_dev;
int i;
mutex_lock(&ts_dev->report_mutex);
for (i = 0; i < GOODIX_MAX_TOUCH; i++) {
@@ -755,9 +951,9 @@ static int goodix_ts_input_report(struct input_dev *dev,
unsigned int touch_num = touch_data->touch_num;
int i, id;
if (core_data->fod_status){
if ((core_data->event_status & 0x20) == 0x20){
ts_info("%s:the data sended was error,return\n",__func__);
if (core_data->fod_status) {
if ((core_data->event_status & 0x20) == 0x20) {
ts_info("%s:the data sended was error,return\n", __func__);
return 0;
}
}
@@ -783,12 +979,8 @@ static int goodix_ts_input_report(struct input_dev *dev,
coords->overlapping_area = 0;
input_report_abs(dev, ABS_MT_WIDTH_MINOR, coords->overlapping_area);
input_report_abs(dev, ABS_MT_WIDTH_MAJOR, coords->overlapping_area);
if (!__test_and_set_bit(i, &core_data->touch_id)) {
if (!__test_and_set_bit(i, &core_data->touch_id))
ts_info("[GTP] %s report press:%d", __func__, i);
}
dev_dbg(core_data->ts_dev->dev, "[GTP] %s report:[%d](%d, %d, %d, %d)", __func__, id,
touch_data->coords[0].x, touch_data->coords[0].y,
touch_data->coords[0].area, touch_data->coords[0].overlapping_area);
id = (++coords)->id;
} else {
if (__test_and_clear_bit(i, &core_data->touch_id)) {
@@ -804,23 +996,20 @@ static int goodix_ts_input_report(struct input_dev *dev,
}
}
/*report finger*/
/*ts_info("get_event_now :0x%02x, pre_event : %d", get_event_now, pre_event);*/
if ((core_data->event_status & 0x88) == 0x88 && core_data->fod_status) {
input_report_key(core_data->input_dev, BTN_INFO, 1);
/*input_report_key(core_data->input_dev, KEY_INFO, 1);*/
core_data->fod_pressed = true;
ts_info("BTN_INFO press");
} else if (core_data->fod_pressed && (core_data->event_status & 0x88) != 0x88) {
input_report_key(core_data->input_dev, BTN_INFO, 1);
core_data->fod_pressed = true;
ts_info("BTN_INFO press");
} else if (core_data->fod_pressed
&& (core_data->event_status & 0x88) != 0x88) {
if (unlikely(!core_data->fod_test)) {
input_report_key(core_data->input_dev, BTN_INFO, 0);
/*input_report_key(core_data->input_dev, KEY_INFO, 0);*/
ts_info("BTN_INFO release");
core_data->fod_pressed = false;
}
}
mutex_unlock(&ts_dev->report_mutex);
input_sync(dev);
mutex_unlock(&ts_dev->report_mutex);
/* check the ghost touch issue */
if (!touch_num && core_data->touch_id) {
ts_err("touch fw miss the up event");
@@ -847,8 +1036,6 @@ static void goodix_ts_sleep_work(struct work_struct *work)
ts_info("pm_resume_completion timeout, i2c is closed");
lpm_disable_for_input(false);
return;
} else {
ts_info("pm_resume_completion be completed, handling irq");
}
}
@@ -921,7 +1108,7 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data)
r = ext_module->funcs->irq_event(core_data, ext_module);
/*ts_err("enter %s r=%d\n", __func__, r);*/
if (r == EVT_CANCEL_IRQEVT) {
ts_err("enter %s EVT_CANCEL_IRQEVT \n", __func__);
ts_err("enter %s EVT_CANCEL_IRQEVT\n", __func__);
mutex_unlock(&goodix_modules.mutex);
lpm_disable_for_input(false);
goto handled;
@@ -959,11 +1146,10 @@ int goodix_ts_irq_setup(struct goodix_ts_core *core_data)
int r;
/* if ts_bdata-> irq is invalid */
if (ts_bdata->irq <= 0) {
if (ts_bdata->irq <= 0)
core_data->irq = gpio_to_irq(ts_bdata->irq_gpio);
} else {
else
core_data->irq = ts_bdata->irq;
}
ts_info("IRQ:%u,flags:%d", core_data->irq, (int)ts_bdata->irq_flags);
r = devm_request_threaded_irq(&core_data->pdev->dev,
@@ -1014,10 +1200,11 @@ EXPORT_SYMBOL(goodix_ts_irq_enable);
static int goodix_ts_power_init(struct goodix_ts_core *core_data)
{
struct goodix_ts_board_data *ts_bdata;
ts_bdata = board_data(core_data);
gpio_direction_output(ts_bdata->reset_gpio, 0);
gpio_direction_output(ts_bdata->irq_gpio, 1);
ts_bdata = board_data(core_data);
gpio_direction_output(ts_bdata->reset_gpio, 0);
gpio_direction_output(ts_bdata->irq_gpio, 1);
return 0;
}
@@ -1032,7 +1219,7 @@ int goodix_ts_power_on(struct goodix_ts_core *core_data)
struct goodix_ts_board_data *ts_bdata = board_data(core_data);
int r = 0;
ts_err("enter::%s\n",__func__);
ts_err("enter::%s\n", __func__);
if (core_data->power_on)
return 0;
gpio_direction_output(ts_bdata->vdd_gpio, 1);
@@ -1199,10 +1386,10 @@ static ssize_t gtp_fod_status_store(struct device *dev,
return count;
}
static DEVICE_ATTR(fod_status, (S_IRUGO | S_IWUSR | S_IWGRP),
static DEVICE_ATTR(fod_status, (0664),
gtp_fod_status_show, gtp_fod_status_store);
static DEVICE_ATTR(fod_test, (S_IRUGO | S_IWUSR | S_IWGRP),
static DEVICE_ATTR(fod_test, (0664),
NULL, gtp_fod_test_store);
static void goodix_switch_mode_work(struct work_struct *work)
@@ -1380,7 +1567,8 @@ int goodix_ts_hw_init(struct goodix_ts_core *core_data)
exit:
/* if bus communication error occured then
* exit driver binding, other errors will
* be ignored */
* be ignored
*/
if (r != -EBUS)
r = 0;
return r;
@@ -1440,13 +1628,12 @@ static void goodix_ts_esd_on(struct goodix_ts_core *core)
{
struct goodix_ts_esd *ts_esd = &core->ts_esd;
if(core->ts_dev->reg.esd == 0)
if (core->ts_dev->reg.esd == 0)
return;
atomic_set(&ts_esd->esd_on, 1);
if (!schedule_delayed_work(&ts_esd->esd_work, GOODIX_ESD_CHECK_INTERVAL * HZ)) {
if (!schedule_delayed_work(&ts_esd->esd_work, GOODIX_ESD_CHECK_INTERVAL * HZ))
ts_info("esd work already in workqueue");
}
ts_info("esd on");
}
@@ -1559,19 +1746,16 @@ int goodix_ts_suspend(struct goodix_ts_core *core_data)
r = ext_module->funcs->before_suspend(core_data, ext_module);
if (r == EVT_CANCEL_SUSPEND) {
if (core_data->double_wakeup && (core_data->aod_status || core_data->fod_status)) {
if (core_data->double_wakeup && (core_data->aod_status || core_data->fod_status))
atomic_set(&core_data->suspend_stat, TP_GESTURE_DBCLK_FOD);
} else if (core_data->double_wakeup && (!core_data->aod_status)) {
else if (core_data->double_wakeup && (!core_data->aod_status))
atomic_set(&core_data->suspend_stat, TP_GESTURE_DBCLK);
} else if (core_data->fod_status && core_data->aod_status) {
else if (core_data->fod_status && core_data->aod_status)
atomic_set(&core_data->suspend_stat, TP_GESTURE_FOD);
}
mutex_unlock(&goodix_modules.mutex);
ts_info("suspend_stat[%d]", atomic_read(&core_data->suspend_stat));
ts_info("Canceled by module:%s", ext_module->name);
if(!atomic_read(&core_data->suspend_stat))
ts_info("go suspend remaind work\n");
else
if (atomic_read(&core_data->suspend_stat))
goto out;
}
}
@@ -1697,7 +1881,7 @@ out:
*/
goodix_ts_blocking_notify(NOTIFY_RESUME, NULL);
ts_err("core_data->fod_pressed = %d\n",core_data->fod_pressed);
ts_err("core_data->fod_pressed = %d\n", core_data->fod_pressed);
if (!core_data->fod_pressed) {
ts_err("resume release all touch");
@@ -1715,6 +1899,7 @@ static int goodix_bl_state_chg_callback(struct notifier_block *nb, unsigned long
{
struct goodix_ts_core *core_data = container_of(nb, struct goodix_ts_core, bl_notifier);
unsigned int blank;
if (val != BACKLIGHT_UPDATED)
return NOTIFY_OK;
if (data && core_data) {
@@ -1814,9 +1999,9 @@ static void goodix_ts_suspend_work(struct work_struct *work)
static int goodix_ts_pm_suspend(struct device *dev)
{
struct goodix_ts_core *core_data = dev_get_drvdata(dev);
if (device_may_wakeup(dev) && core_data->gesture_enabled) {
if (device_may_wakeup(dev) && core_data->gesture_enabled)
enable_irq_wake(core_data->irq);
}
core_data->tp_already_suspend = true;
reinit_completion(&core_data->pm_resume_completion);
@@ -1831,9 +2016,8 @@ static int goodix_ts_pm_resume(struct device *dev)
{
struct goodix_ts_core *core_data =
dev_get_drvdata(dev);
if (device_may_wakeup(dev) && core_data->gesture_enabled) {
if (device_may_wakeup(dev) && core_data->gesture_enabled)
disable_irq_wake(core_data->irq);
}
core_data->tp_already_suspend = false;
complete(&core_data->pm_resume_completion);
@@ -1962,7 +2146,8 @@ int goodix_generic_noti_callback(struct notifier_block *self,
/* Firmware has been updated, we need to reinit
* the chip, read the sensor ID and send the
* correct config data based on sensor ID.
* The input parameters also needs to be updated.*/
* The input parameters also needs to be updated.
*/
r = hw_ops->init(ts_core->ts_dev);
if (r < 0)
goto exit;
@@ -2025,7 +2210,7 @@ static int goodix_ts_probe(struct platform_device *pdev)
int r;
u8 read_val = 0;
ts_err("enter::%s\n",__func__);
ts_err("enter::%s\n", __func__);
ts_device = pdev->dev.platform_data;
if (!ts_device || !ts_device->hw_ops ||
!ts_device->board_data) {
@@ -2034,10 +2219,8 @@ static int goodix_ts_probe(struct platform_device *pdev)
}
core_data = devm_kzalloc(&pdev->dev, sizeof(struct goodix_ts_core), GFP_KERNEL);
if (!core_data) {
ts_err("Failed to allocate memory for core data");
if (!core_data)
return -ENOMEM;
}
goodix_core_data = core_data;
/* touch core layer is a platform driver */
@@ -2051,13 +2234,13 @@ static int goodix_ts_probe(struct platform_device *pdev)
r = goodix_ts_power_init(core_data);
if (r < 0) {
pr_err("goodix_ts_power_init fail \n");
pr_err("goodix_ts_power_init fail\n");
goto out;
}
r = goodix_ts_power_on(core_data);
if (r < 0) {
pr_err("goodix_ts_power_on fail \n");
pr_err("goodix_ts_power_on fail\n");
goto out;
}
@@ -2074,7 +2257,7 @@ static int goodix_ts_probe(struct platform_device *pdev)
/* get GPIO resource */
r = goodix_ts_gpio_setup(core_data);
if (r < 0) {
pr_err("goodix_ts_gpio_setup fail \n");
pr_err("goodix_ts_gpio_setup fail\n");
goto out;
}
/*init lock to protect suspend_stat*/
@@ -2089,7 +2272,7 @@ static int goodix_ts_probe(struct platform_device *pdev)
r = ts_device->hw_ops->reset(ts_device);
if (r < 0) {
pr_err("goodix_hw_ops->reset fail \n");
pr_err("goodix_hw_ops->reset fail\n");
goto out;
}
@@ -2117,14 +2300,11 @@ static int goodix_ts_probe(struct platform_device *pdev)
}
/*unified protocl
* start a thread to parse cfg_bin and init IC*/
* start a thread to parse cfg_bin and init IC
*/
r = goodix_start_cfg_bin(core_data);
if (!r) {
ts_info("***start cfg_bin_proc SUCCESS");
} else {
ts_err("***start cfg_bin_proc FAILED");
if (r)
goto out;
}
core_data->power_supply_notifier.notifier_call = gtp_power_supply_event;
power_supply_reg_notifier(&core_data->power_supply_notifier);
@@ -2168,9 +2348,13 @@ static int goodix_ts_probe(struct platform_device *pdev)
}
#endif
#ifdef CONFIG_TOUCHSCREEN_GOODIX_GTX8_GAMEMODE
gtp_init_touchmode_data();
#endif
out:
backlight_unregister_notifier(&core_data->bl_notifier);
ts_info("goodix_ts_probe OUT, r:%d", r);
ts_info("%s OUT, r:%d", __func__, r);
return r;
}

View File

@@ -93,6 +93,30 @@
#define GTP_GAME_CMD 0x0E
#define GTP_EXIT_GAME_CMD 0x0F
#ifdef CONFIG_TOUCHSCREEN_GOODIX_GTX8_GAMEMODE
/*CUR, DEFAULT, MIN, MAX*/
#define VALUE_TYPE_SIZE 6
#define VALUE_GRIP_SIZE 9
enum MODE_CMD {
SET_CUR_VALUE = 0,
GET_CUR_VALUE,
GET_DEF_VALUE,
GET_MIN_VALUE,
GET_MAX_VALUE,
GET_MODE_VALUE,
RESET_MODE,
};
enum MODE_TYPE {
Touch_Game_Mode = 0,
Touch_Tolerance = 1,
Touch_UP_THRESHOLD = 2,
Touch_Edge_Filter = 3,
Touch_Panel_Orientation = 4,
Touch_Mode_NUM = 5,
};
#endif
#define CONFIG_TOUCHSCREEN_GOODIX_DEBUG_FS
/*
@@ -477,6 +501,9 @@ struct goodix_ts_core {
int fod_test;
int double_wakeup;
int result_type;
#ifdef CONFIG_TOUCHSCREEN_GOODIX_GTX8_GAMEMODE
int touch_mode[Touch_Mode_NUM][VALUE_TYPE_SIZE];
#endif
struct class *gtp_tp_class;
struct device *gtp_touch_dev;
char *current_clicknum_file;
@@ -577,7 +604,7 @@ struct goodix_ext_attribute {
/* external attrs helper macro, used to define external attrs */
#define DEFINE_EXTMOD_ATTR(_name, _mode, _show, _store) \
static struct goodix_ext_attribute ext_attr_##_name = \
__EXTMOD_ATTR(_name, _mode, _show, _store);
__EXTMOD_ATTR(_name, _mode, _show, _store)
/*
* get board data pointer
@@ -617,6 +644,7 @@ static inline u8 checksum_u8(u8 *data, u32 size)
{
u8 checksum = 0;
u32 i;
for (i = 0; i < size; i++)
checksum += data[i];
return checksum;
@@ -636,6 +664,7 @@ static inline u16 checksum_be16(u8 *data, u32 size)
{
u16 checksum = 0;
u32 i;
for (i = 0; i < size; i += 2)
checksum += be16_to_cpup((__be16 *)(data + i));
return checksum;
@@ -645,6 +674,7 @@ static inline u32 checksum_le32(u8 *data, u32 size)
{
u32 checksum = 0;
u32 i;
for (i = 0; i < size; i += 4)
checksum += le32_to_cpup((__le32 *)(data + i));
return checksum;
@@ -654,6 +684,7 @@ static inline u32 checksum_be32(u8 *data, u32 size)
{
u32 checksum = 0;
u32 i;
for (i = 0; i < size; i += 4)
checksum += be32_to_cpup((__be32 *)(data + i));
return checksum;
@@ -675,7 +706,8 @@ static inline u32 checksum_be32(u8 *data, u32 size)
* 2. you want the flow of this event continue, in
* this condition, you should return EVT_HANDLED in
* the callback function.
* */
*
*/
#define EVT_HANDLED 0
#define EVT_CONTINUE 0
#define EVT_CANCEL 1
@@ -747,10 +779,10 @@ int goodix_ts_blocking_notify(enum ts_notify_event evt, void *v);
/**
* * goodix_ts_power_on - Turn on power to the touch device
* * @core_data: pointer to touch core data
* * return: 0 ok, <0 failed
* */
* goodix_ts_power_on - Turn on power to the touch device
* @core_data: pointer to touch core data
* return: 0 ok, <0 failed
*/
int goodix_ts_power_on(struct goodix_ts_core *core_data);
/**

View File

@@ -56,7 +56,7 @@ static int FP_Event_Gesture;
* @gesture_type: store valied gesture type,each bit stand for a gesture
* @gesture_data: gesture data
* @gesture_ts_cmd: gesture command data
*/
*/
struct gesture_module {
atomic_t registered;
unsigned int kobj_initialized;
@@ -147,9 +147,10 @@ static ssize_t gsx_gesture_enable_store(struct goodix_ext_module *module,
const char *buf, size_t count)
{
unsigned int tmp;
int ret;
int ret, rc;
if (sscanf(buf, "%u", &tmp) != 1) {
rc = kstrtoint(buf, 0, &tmp);
if (rc != 0) {
ts_info("Parameter illegal");
return -EINVAL;
}
@@ -230,9 +231,8 @@ int goodix_sync_ic_stat(struct goodix_ts_core *core_data)
int tp_stat;
int ret = 0;
if (!core_data) {
if (!core_data)
ts_err("parameter illegal");
}
mutex_lock(&core_data->work_stat);
tp_stat = atomic_read(&core_data->suspend_stat);
@@ -257,9 +257,8 @@ int goodix_sync_ic_stat(struct goodix_ts_core *core_data)
int goodix_check_gesture_stat(bool enable)
{
if (enable) {
if (enable)
goodix_sync_ic_stat(goodix_core_data);
}
return 0;
}
/**
@@ -359,7 +358,7 @@ static int gsx_gesture_init(struct goodix_ts_core *core_data,
goto exit_gesture_init;
}
for (i = 0; i < sizeof(gesture_attrs)/sizeof(gesture_attrs[0]); i++) {
for (i = 0; i < ARRAY_SIZE(gesture_attrs); i++) {
if (sysfs_create_file(&module->kobj,
&gesture_attrs[i].attr)) {
ts_err("Create sysfs attr file error");
@@ -614,18 +613,16 @@ static int goodix_wakeup_and_set_suspend_func(struct goodix_ts_core *core_data)
/*start suspend*/
do {
r = goodix_set_suspend_func(core_data);
if (r < 0) {
if (r < 0)
ts_info("Send doze command failed, retry");
}
} while (r < 0 && ++retry < 3);
if (core_data->double_wakeup && (core_data->fod_status || core_data->aod_status)) {
if (core_data->double_wakeup && (core_data->fod_status || core_data->aod_status))
atomic_set(&core_data->suspend_stat, TP_GESTURE_DBCLK_FOD);
} else if (core_data->double_wakeup) {
else if (core_data->double_wakeup)
atomic_set(&core_data->suspend_stat, TP_GESTURE_DBCLK);
} else if (core_data->fod_status || core_data->aod_status) {
else if (core_data->fod_status || core_data->aod_status)
atomic_set(&core_data->suspend_stat, TP_GESTURE_FOD);
}
ts_info("suspend_stat[%d]", atomic_read(&core_data->suspend_stat));
/*finish suspend*/
@@ -655,10 +652,10 @@ static int gsx_gesture_before_suspend(struct goodix_ts_core *core_data,
}
if (!core_data->gesture_enabled) {
ts_err("enter %s\n", __func__);
atomic_set(&core_data->suspended, 1);
return EVT_CONTINUE;
}
ts_err("enter %s\n", __func__);
atomic_set(&core_data->suspended, 1);
return EVT_CONTINUE;
}
ret = goodix_set_suspend_func(core_data);
if (ret != 0) {
@@ -700,6 +697,7 @@ static int __init goodix_gsx_gesture_init(void)
{
/* initialize core_data->ts_dev->gesture_cmd*/
int result;
ts_info("gesture module init");
gsx_gesture = kzalloc(sizeof(struct gesture_module), GFP_KERNEL);
if (!gsx_gesture)

View File

@@ -90,7 +90,7 @@ int pre_event;
* @node: devicetree node
* @board_data: pointer to board data structure
* return: 0 - no error, <0 error
*/
*/
static int goodix_parse_dt_resolution(struct device_node *node,
struct goodix_ts_board_data *board_data)
{
@@ -147,14 +147,14 @@ static int goodix_parse_dt_resolution(struct device_node *node,
* @dev: pointer to device
* @board_data: pointer to board data structure
* return: 0 - no error, <0 error
*/
*/
static int goodix_parse_dt(struct device_node *node,
struct goodix_ts_board_data *board_data)
{
struct property *prop;
int r;
ts_err("enter::%s\n",__func__);
ts_err("enter::%s\n", __func__);
if (!board_data) {
ts_err("Invalid board data");
return -EINVAL;
@@ -223,7 +223,8 @@ static int goodix_parse_dt(struct device_node *node,
&board_data->power_on_delay_us);
if (!r) {
/* 1000ms is too large, maybe you have pass
* a wrong value */
* a wrong value
*/
if (board_data->power_on_delay_us > 1000 * 1000) {
ts_err("Power on delay time exceed 1s, please check");
board_data->power_on_delay_us = 0;
@@ -234,7 +235,8 @@ static int goodix_parse_dt(struct device_node *node,
&board_data->power_off_delay_us);
if (!r) {
/* 1000ms is too large, maybe you have pass
* a wrong value */
* a wrong value
*/
if (board_data->power_off_delay_us > 1000 * 1000) {
ts_err("Power off delay time exceed 1s, please check");
board_data->power_off_delay_us = 0;
@@ -308,7 +310,7 @@ static int goodix_parse_dt(struct device_node *node,
* @board_data: board data
* @sensor_id: sensor ID
* return: 0 - read ok, < 0 - i2c transter error
*/
*/
static int goodix_parse_customize_params(struct goodix_ts_device *dev,
struct goodix_ts_board_data *board_data,
unsigned int sensor_id)
@@ -374,7 +376,7 @@ static int goodix_parse_acpi_cfg(struct acpi_device *dev,
* @data: read buffer
* @len: bytes to read
* return: 0 - read ok, < 0 - i2c transter error
*/
*/
int goodix_i2c_read_trans(struct goodix_ts_device *dev, unsigned int reg,
unsigned char *data, unsigned int len)
{
@@ -400,11 +402,9 @@ int goodix_i2c_read_trans(struct goodix_ts_device *dev, unsigned int reg,
msgs[1].buf = &get_buf[0];
} else {
msgs[1].buf = kzalloc(I2C_MAX_TRANSFER_SIZE < len
? I2C_MAX_TRANSFER_SIZE : len, GFP_KERNEL);
if (msgs[1].buf == NULL) {
ts_err("Malloc failed");
? I2C_MAX_TRANSFER_SIZE : len, GFP_KERNEL);
if (msgs[1].buf == NULL)
return -ENOMEM;
}
}
while (pos != len) {
@@ -448,7 +448,7 @@ read_exit:
* @data: write buffer
* @len: bytes to write
* return: 0 - write ok; < 0 - i2c transter error.
*/
*/
int goodix_i2c_write_trans(struct goodix_ts_device *dev, unsigned int reg,
unsigned char *data, unsigned int len)
{
@@ -469,10 +469,8 @@ int goodix_i2c_write_trans(struct goodix_ts_device *dev, unsigned int reg,
msg.buf = kmalloc(I2C_MAX_TRANSFER_SIZE < len + TS_ADDR_LENGTH
? I2C_MAX_TRANSFER_SIZE : len + TS_ADDR_LENGTH,
GFP_KERNEL);
if (msg.buf == NULL) {
ts_err("Malloc failed");
if (msg.buf == NULL)
return -ENOMEM;
}
}
while (pos != len) {
@@ -519,7 +517,7 @@ write_exit:
* mode, then you must enable it again.
* Between set_doze_false and set_doze_true, do not reset
* IC!
*/
*/
static int goodix_set_i2c_doze_mode(struct goodix_ts_device *dev, int enable)
{
static DEFINE_MUTEX(doze_mode_lock);
@@ -560,10 +558,10 @@ static int goodix_set_i2c_doze_mode(struct goodix_ts_device *dev, int enable)
usleep_range(1000, 1100);
for (i = 0; i < TS_DOZE_DISABLE_RETRY_TIMES; i++) {
goodix_i2c_read_trans(dev, TS_REG_DOZE_STAT, &r_data, 1);
if (TS_DOZE_CLOSE_OK_DATA == r_data) {
if (r_data == TS_DOZE_CLOSE_OK_DATA) {
result = 0;
goto exit;
} else if (0xAA != r_data) {
} else if (r_data != 0xAA) {
w_data = TS_DOZE_DISABLE_DATA;
goodix_i2c_write_trans(dev, TS_REG_DOZE_CTRL, &w_data, 1);
}
@@ -588,7 +586,7 @@ exit:
* @data: write buffer
* @len: bytes to write
* return: 0 - write ok; < 0 - i2c transter error.
*/
*/
int goodix_i2c_write(struct goodix_ts_device *dev, unsigned int reg,
unsigned char *data, unsigned int len)
{
@@ -618,7 +616,7 @@ int goodix_i2c_write(struct goodix_ts_device *dev, unsigned int reg,
* @data: read buffer
* @len: bytes to read
* return: 0 - read ok, < 0 - i2c transter error
*/
*/
int goodix_i2c_read(struct goodix_ts_device *dev, unsigned int reg,
unsigned char *data, unsigned int len)
{
@@ -646,7 +644,7 @@ int goodix_i2c_read(struct goodix_ts_device *dev, unsigned int reg,
* @data: write buffer
* @len: bytes to write
* return: 0 - write ok; < 0 - i2c transter error.
*/
*/
int goodix_i2c_write_trans_once(struct goodix_ts_device *dev, unsigned int reg,
unsigned char *data, unsigned int len)
{
@@ -765,7 +763,8 @@ static int goodix_read_version(struct goodix_ts_device *dev,
}
/*disable doze mode, just valid for normandy
* this func must be used in pairs*/
* this func must be used in pairs
*/
goodix_set_i2c_doze_mode(dev, false);
/*check checksum*/
@@ -854,7 +853,8 @@ static int goodix_read_version(struct goodix_ts_device *dev,
exit:
/*enable doze mode, just valid for normandy
* this func must be used in pairs*/
* this func must be used in pairs
*/
goodix_set_i2c_doze_mode(dev, true);
return r;
@@ -1017,6 +1017,7 @@ static int goodix_check_cfg_valid(struct goodix_ts_device *dev, u8 *cfg, u32 len
int i, j;
int bag_start = 0;
int bag_end = 0;
if (!cfg || length < TS_CFG_HEAD_LEN) {
ts_err("cfg is INVALID, len:%d", length);
ret = -EINVAL;
@@ -1099,11 +1100,6 @@ static int goodix_send_config(struct goodix_ts_device *dev,
{
int r = 0;
/*check reg valid*/
/* if (!dev->reg.cfg_addr) {
ts_err("cfg register is NULL");
return -EINVAL;
}*/
if (!config || !*(config->data)) {
ts_err("Null config data");
return -EINVAL;
@@ -1145,51 +1141,12 @@ static int goodix_send_config(struct goodix_ts_device *dev,
return r;
}
#if 0
/**
* goodix_send_config - send config data to device.
* @dev: pointer to device
* @config: pointer to config data struct to be send
* @return: 0 - succeed, < 0 - failed
*/
static int goodix_send_config(struct goodix_ts_device *dev,
struct goodix_ts_config *config)
{
int r = 0;
if (!config || !config->data) {
ts_err("Null config data");
return -EINVAL;
}
ts_info("Send %s,ver:%02xh,size:%d",
config->name, config->data[0],
config->length);
mutex_lock(&config->lock);
r = goodix_i2c_write(dev, config->reg_base,
config->data, config->length);
if (r)
goto exit;
/* make sure the firmware accept the config data*/
if (config->delay)
msleep(config->delay);
exit:
mutex_unlock(&config->lock);
return r;
}
#endif
/**
* goodix_close_hidi2c_mode
* Called by touch core module when bootup
* @ts_dev: pointer to touch device
* return: 0 - no error, <0 error
*/
*/
static int goodix_close_hidi2c_mode(struct goodix_ts_device *ts_dev)
{
int r = 0;
@@ -1207,7 +1164,7 @@ static int goodix_close_hidi2c_mode(struct goodix_ts_device *ts_dev)
usleep_range(10000, 11000);
}
if (try_times >= 10) {
ts_info("goodix_close_hidi2c_mode FAILED, 0x8040 is not equal to 0xff");
ts_info("%s FAILED, 0x8040 is not equal to 0xff", __func__);
return -EINVAL;
}
@@ -1404,7 +1361,7 @@ exit:
* Called by touch core module when bootup
* @ts_dev: pointer to touch device
* return: 0 - no error, <0 error
*/
*/
static int goodix_hw_init(struct goodix_ts_device *ts_dev)
{
int r;
@@ -1415,19 +1372,15 @@ static int goodix_hw_init(struct goodix_ts_device *ts_dev)
if (!ts_dev->normal_cfg) {
ts_dev->normal_cfg = devm_kzalloc(ts_dev->dev,
sizeof(*ts_dev->normal_cfg), GFP_KERNEL);
if (!ts_dev->normal_cfg) {
ts_err("Failed to alloc memory for normal cfg");
if (!ts_dev->normal_cfg)
return -ENOMEM;
}
mutex_init(&ts_dev->normal_cfg->lock);
}
if (!ts_dev->highsense_cfg) {
ts_dev->highsense_cfg = devm_kzalloc(ts_dev->dev,
sizeof(*ts_dev->highsense_cfg), GFP_KERNEL);
if (!ts_dev->highsense_cfg) {
ts_err("Failed to alloc memory for high sense cfg");
if (!ts_dev->highsense_cfg)
return -ENOMEM;
}
mutex_init(&ts_dev->highsense_cfg->lock);
}
@@ -1446,13 +1399,14 @@ static int goodix_hw_init(struct goodix_ts_device *ts_dev)
/* devicetree property like resolution(panel_max_xxx)
* may be different between sensors, here we try to parse
* parameters form sensor child node */
* parameters form sensor child node
*/
r = goodix_parse_customize_params(ts_dev,
ts_dev->board_data,
ts_dev->chip_version.sensor_id);
if (r < 0)
ts_info("Cann't find customized parameters");
ts_dev->normal_cfg->delay = 500;
/* send normal-cfg to firmware */
r = goodix_send_config(ts_dev, ts_dev->normal_cfg);
@@ -1538,7 +1492,7 @@ static int goodix_request_handler(struct goodix_ts_device *dev,
unsigned char buffer[1];
int r;
if (dev->reg.fw_request != 0x6F6D){
if (dev->reg.fw_request != 0x6F6D) {
ts_info("firmware reg is wrong!\n");
dev->reg.fw_request = 0x6F6D;
}
@@ -1584,6 +1538,7 @@ static void goodix_swap_coords(struct goodix_ts_device *dev,
{
int i, temp;
struct goodix_ts_board_data *bdata = dev->board_data;
for (i = 0; i < touch_num; i++) {
if (bdata->swap_axis) {
temp = coords->x;
@@ -1694,16 +1649,8 @@ static int goodix_remap_trace_id(struct goodix_ts_device *dev,
}
offset += BYTES_PER_COORD;
}
}
/*for (i = 0; i < touch_num; i++) {
ts_info("remap data%d:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x",
i, coor_buf[i * 8], coor_buf[i * 8 + 1],
coor_buf[i * 8 + 2], coor_buf[i * 8 + 3],
coor_buf[i * 8 + 4], coor_buf[i * 8 + 5],
coor_buf[i * 8 + 6], coor_buf[i * 8 + 7]);
}*/
}
/*realign coor data by new trace ID*/
for (i = 0; i < touch_num - 1; i++) {
@@ -1726,15 +1673,6 @@ static int goodix_remap_trace_id(struct goodix_ts_device *dev,
BYTES_PER_COORD);
}
}
/*for (i = 0; i < touch_num; i++) {
ts_info("final data%d:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x",
i, coor_buf[i * 8], coor_buf[i * 8 + 1],
coor_buf[i * 8 + 2], coor_buf[i * 8 + 3],
coor_buf[i * 8 + 4], coor_buf[i * 8 + 5],
coor_buf[i * 8 + 6], coor_buf[i * 8 + 7]);
}*/
return 0;
}
@@ -1784,7 +1722,8 @@ static int goodix_touch_handler(struct goodix_ts_device *dev,
}
/* touch_num * BYTES_PER_COORD + 1(touch event state)
* + 1(checksum) + 1(key value) */
* + 1(checksum) + 1(key value)
*/
if (dev->ic_type == IC_TYPE_NANJING) {
chksum = checksum_u8(&buffer[1],
touch_num * BYTES_PER_COORD + 3);
@@ -1807,18 +1746,6 @@ static int goodix_touch_handler(struct goodix_ts_device *dev,
touch_data->key_value = (touch_data->key_value & 0x0f) |
((touch_data->key_value & 0xf0) >> (4 - dev->board_data->tp_key_num));
}
/*ts_info("$$$$$$coord_sta:0x%02x, have_key:%d, key_value:0x%02x",
coord_sta, touch_data->have_key, touch_data->key_value);*/
/*for (i = 0; i < touch_num; i++) {
ts_info("raw coor data%d:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x",
i, buffer[i * 8 + 2], buffer[i * 8 + 3],
buffer[i * 8 + 4], buffer[i * 8 + 5],
buffer[i * 8 + 6], buffer[i * 8 + 7],
buffer[i * 8 + 8], buffer[i * 8 + 9]);
}*/
/*add end*/
/*remap trace id*/
if (dev->ic_type == IC_TYPE_NANJING)
@@ -1867,22 +1794,21 @@ static int goodix_touch_handler(struct goodix_ts_device *dev,
buffer[i * BYTES_PER_COORD + 7] |
(buffer[i * BYTES_PER_COORD + 8] << 8);
}
} else {/*it's a finger*/
coords->id = buffer[i * BYTES_PER_COORD + 2] & 0x0f;
coords->x = buffer[i * BYTES_PER_COORD + 3] |
(buffer[i * BYTES_PER_COORD + 4] << 8);
coords->y = buffer[i * BYTES_PER_COORD + 5] |
(buffer[i * BYTES_PER_COORD + 6] << 8);
coords->w = coords->p / 16;
coords->p = buffer[i * BYTES_PER_COORD + 7] |
(buffer[i * BYTES_PER_COORD + 8] << 8);
coords->overlapping_area = buffer[8];
coords->area = buffer[i * BYTES_PER_COORD + 9];
/*ts_debug("EF:[%d](%d, %d)", coords->id, coords->x, coords->y);*/
if (touch_data->pen_down == true) {
touch_data->pen_down = false;
/*ts_info("***pen leave");*/
}
/*it's a finger*/
} else {
coords->id = buffer[i * BYTES_PER_COORD + 2] & 0x0f;
coords->x = buffer[i * BYTES_PER_COORD + 3] |
(buffer[i * BYTES_PER_COORD + 4] << 8);
coords->y = buffer[i * BYTES_PER_COORD + 5] |
(buffer[i * BYTES_PER_COORD + 6] << 8);
coords->w = coords->p / 16;
coords->p = buffer[i * BYTES_PER_COORD + 7] |
(buffer[i * BYTES_PER_COORD + 8] << 8);
coords->overlapping_area = buffer[8];
coords->area = buffer[i * BYTES_PER_COORD + 9];
/*ts_debug("EF:[%d](%d, %d)", coords->id, coords->x, coords->y);*/
if (touch_data->pen_down == true)
touch_data->pen_down = false;
}
}
@@ -2099,9 +2025,9 @@ static int goodix_i2c_probe(struct i2c_client *client,
struct goodix_ts_board_data *ts_bdata = NULL;
int r = 0;
ts_err("enter::%s\n",__func__);
ts_err("enter::%s\n", __func__);
r = i2c_check_functionality(client->adapter,I2C_FUNC_I2C);
r = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
if (!r)
return -EIO;
@@ -2118,11 +2044,11 @@ static int goodix_i2c_probe(struct i2c_client *client,
return r;
}
#ifdef CONFIG_ACPI
else if (ACPI_COMPANION(&client->dev)) {
else if (ACPI_COMPANION(&client->dev)) {
r = goodix_parse_acpi(&client->dev, ts_bdata);
if (r < 0)
return r;
}
}
#endif
else {
/* use platform data */
@@ -2143,7 +2069,7 @@ static int goodix_i2c_probe(struct i2c_client *client,
ts_device->dev = &client->dev;
ts_device->board_data = ts_bdata;
ts_device->hw_ops = &hw_i2c_ops;
/* ts core device */
goodix_pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
@@ -2162,7 +2088,8 @@ static int goodix_i2c_probe(struct i2c_client *client,
goodix_pdev->dev.release = goodix_pdev_release;
/* register platform device, then the goodix_ts_core
* module will probe the touch deivce. */
* module will probe the touch deivce.
*/
r = platform_device_register(goodix_pdev);
ts_info("goodix9886_i2c_probe OUT");

View File

@@ -296,7 +296,7 @@ err_out:
*/
int sync_read_rawdata (unsigned int reg,
int sync_read_rawdata(unsigned int reg,
unsigned char *data, unsigned int len)
{
@@ -601,6 +601,7 @@ static long goodix_tools_compat_ioctl(struct file *file, unsigned int cmd,
static int goodix_tools_open(struct inode *inode, struct file *filp)
{
int ret = 0;
filp->private_data = goodix_tools_dev;
ts_info("tools open");
/* Only the first time open device need to register module */

View File

@@ -959,7 +959,9 @@ iova_magazine_free_pfns(struct iova_magazine *mag, struct iova_domain *iovad)
for (i = 0 ; i < mag->size; ++i) {
struct iova *iova = private_find_iova(iovad, mag->pfns[i]);
BUG_ON(!iova);
if (WARN_ON(!iova))
continue;
private_free_iova(iovad, iova);
}

View File

@@ -159,7 +159,13 @@ static long cec_adap_g_log_addrs(struct cec_adapter *adap,
struct cec_log_addrs log_addrs;
mutex_lock(&adap->lock);
log_addrs = adap->log_addrs;
/*
* We use memcpy here instead of assignment since there is a
* hole at the end of struct cec_log_addrs that an assignment
* might ignore. So when we do copy_to_user() we could leak
* one byte of memory.
*/
memcpy(&log_addrs, &adap->log_addrs, sizeof(log_addrs));
if (!adap->is_configured)
memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID,
sizeof(log_addrs.log_addr));

View File

@@ -423,14 +423,15 @@ static void debiirq(unsigned long cookie)
case DATA_CI_GET:
{
u8 *data = av7110->debi_virt;
u8 data_0 = data[0];
if ((data[0] < 2) && data[2] == 0xff) {
if (data_0 < 2 && data[2] == 0xff) {
int flags = 0;
if (data[5] > 0)
flags |= CA_CI_MODULE_PRESENT;
if (data[5] > 5)
flags |= CA_CI_MODULE_READY;
av7110->ci_slot[data[0]].flags = flags;
av7110->ci_slot[data_0].flags = flags;
} else
ci_get_data(&av7110->ci_rbuffer,
av7110->debi_virt,

View File

@@ -1489,8 +1489,6 @@ probe_out:
/* Unregister video device */
video_unregister_device(&ch->video_dev);
}
kfree(vpif_obj.sd);
v4l2_device_unregister(&vpif_obj.v4l2_dev);
return err;
}

View File

@@ -87,13 +87,8 @@ static int gpio_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
// space
edge = ktime_add_us(edge, txbuf[i]);
delta = ktime_us_delta(edge, ktime_get());
if (delta > 10) {
spin_unlock_irqrestore(&gpio_ir->lock, flags);
usleep_range(delta, delta + 10);
spin_lock_irqsave(&gpio_ir->lock, flags);
} else if (delta > 0) {
if (delta > 0)
udelay(delta);
}
} else {
// pulse
ktime_t last = ktime_add_us(edge, txbuf[i]);

View File

@@ -176,6 +176,9 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
/* EBG */
{ PCI_VDEVICE(INTEL, 0x1bad), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x1bae), (kernel_ulong_t)&bxt_uart_info },
/* GLK */
{ PCI_VDEVICE(INTEL, 0x31ac), (kernel_ulong_t)&glk_i2c_info },
{ PCI_VDEVICE(INTEL, 0x31ae), (kernel_ulong_t)&glk_i2c_info },

View File

@@ -844,8 +844,10 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
continue;
err = gfar_parse_group(child, priv, model);
if (err)
if (err) {
of_node_put(child);
goto err_grp_init;
}
}
} else { /* SQ_SG_MODE */
err = gfar_parse_group(np, priv, model);

View File

@@ -187,12 +187,21 @@ static void ipvlan_port_destroy(struct net_device *dev)
kfree(port);
}
#define IPVLAN_ALWAYS_ON_OFLOADS \
(NETIF_F_SG | NETIF_F_HW_CSUM | \
NETIF_F_GSO_ROBUST | NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL)
#define IPVLAN_ALWAYS_ON \
(IPVLAN_ALWAYS_ON_OFLOADS | NETIF_F_LLTX | NETIF_F_VLAN_CHALLENGED)
#define IPVLAN_FEATURES \
(NETIF_F_SG | NETIF_F_CSUM_MASK | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
(NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
NETIF_F_GSO | NETIF_F_TSO | NETIF_F_GSO_ROBUST | \
NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
/* NETIF_F_GSO_ENCAP_ALL NETIF_F_GSO_SOFTWARE Newly added */
#define IPVLAN_STATE_MASK \
((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
@@ -205,7 +214,9 @@ static int ipvlan_init(struct net_device *dev)
dev->state = (dev->state & ~IPVLAN_STATE_MASK) |
(phy_dev->state & IPVLAN_STATE_MASK);
dev->features = phy_dev->features & IPVLAN_FEATURES;
dev->features |= NETIF_F_LLTX;
dev->features |= IPVLAN_ALWAYS_ON;
dev->vlan_features = phy_dev->vlan_features & IPVLAN_FEATURES;
dev->vlan_features |= IPVLAN_ALWAYS_ON_OFLOADS;
dev->gso_max_size = phy_dev->gso_max_size;
dev->gso_max_segs = phy_dev->gso_max_segs;
dev->hard_header_len = phy_dev->hard_header_len;
@@ -293,7 +304,14 @@ static netdev_features_t ipvlan_fix_features(struct net_device *dev,
{
struct ipvl_dev *ipvlan = netdev_priv(dev);
return features & (ipvlan->sfeatures | ~IPVLAN_FEATURES);
features |= NETIF_F_ALL_FOR_ALL;
features &= (ipvlan->sfeatures | ~IPVLAN_FEATURES);
features = netdev_increment_features(ipvlan->phy_dev->features,
features, features);
features |= IPVLAN_ALWAYS_ON;
features &= (IPVLAN_FEATURES | IPVLAN_ALWAYS_ON);
return features;
}
static void ipvlan_change_rx_flags(struct net_device *dev, int change)
@@ -743,10 +761,9 @@ static int ipvlan_device_event(struct notifier_block *unused,
case NETDEV_FEAT_CHANGE:
list_for_each_entry(ipvlan, &port->ipvlans, pnode) {
ipvlan->dev->features = dev->features & IPVLAN_FEATURES;
ipvlan->dev->gso_max_size = dev->gso_max_size;
ipvlan->dev->gso_max_segs = dev->gso_max_segs;
netdev_features_change(ipvlan->dev);
netdev_update_features(ipvlan->dev);
}
break;

View File

@@ -755,7 +755,7 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
#define TARGET_10_4_TX_DBG_LOG_SIZE 1024
#define TARGET_10_4_NUM_WDS_ENTRIES 32
#define TARGET_10_4_DMA_BURST_SIZE 0
#define TARGET_10_4_DMA_BURST_SIZE 1
#define TARGET_10_4_MAC_AGGR_DELIM 0
#define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1
#define TARGET_10_4_VOW_CONFIG 0

View File

@@ -739,8 +739,11 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
usb_anchor_urb(urb, &rtlusb->rx_submitted);
err = usb_submit_urb(urb, GFP_KERNEL);
if (err)
if (err) {
usb_unanchor_urb(urb);
usb_free_urb(urb);
goto err_out;
}
usb_free_urb(urb);
}
return 0;

View File

@@ -1492,7 +1492,7 @@ __nvme_fc_init_request(struct nvme_fc_ctrl *ctrl,
if (fc_dma_mapping_error(ctrl->lport->dev, op->fcp_req.cmddma)) {
dev_err(ctrl->dev,
"FCP Op failed - cmdiu dma mapping failed.\n");
ret = EFAULT;
ret = -EFAULT;
goto out_on_error;
}
@@ -1502,7 +1502,7 @@ __nvme_fc_init_request(struct nvme_fc_ctrl *ctrl,
if (fc_dma_mapping_error(ctrl->lport->dev, op->fcp_req.rspdma)) {
dev_err(ctrl->dev,
"FCP Op failed - rspiu dma mapping failed.\n");
ret = EFAULT;
ret = -EFAULT;
}
atomic_set(&op->state, FCPOP_STATE_IDLE);

View File

@@ -303,13 +303,16 @@ placeholder:
slot_name = make_slot_name(name);
if (!slot_name) {
err = -ENOMEM;
kfree(slot);
goto err;
}
err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
"%s", slot_name);
if (err)
if (err) {
kobject_put(&slot->kobj);
goto err;
}
INIT_LIST_HEAD(&slot->list);
list_add(&slot->list, &parent->slots);
@@ -328,7 +331,6 @@ out:
mutex_unlock(&pci_slot_mutex);
return slot;
err:
kfree(slot);
slot = ERR_PTR(err);
goto out;
}

View File

@@ -581,6 +581,11 @@ static int slow_eval_known_fn(struct subchannel *sch, void *data)
rc = css_evaluate_known_subchannel(sch, 1);
if (rc == -EAGAIN)
css_schedule_eval(sch->schid);
/*
* The loop might take long time for platforms with lots of
* known devices. Allow scheduling here.
*/
cond_resched();
}
return 0;
}

View File

@@ -267,9 +267,9 @@ static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new)
WARN_ON(!fcf_dev);
new->fcf_dev = NULL;
fcoe_fcf_device_delete(fcf_dev);
kfree(new);
mutex_unlock(&cdev->lock);
}
kfree(new);
}
/**

View File

@@ -644,27 +644,16 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
vport->port_state < LPFC_VPORT_READY)
return -EAGAIN;
}
/*
* This is a bit of a mess. We want to ensure the shost doesn't get
* torn down until we're done with the embedded lpfc_vport structure.
*
* Beyond holding a reference for this function, we also need a
* reference for outstanding I/O requests we schedule during delete
* processing. But once we scsi_remove_host() we can no longer obtain
* a reference through scsi_host_get().
*
* So we take two references here. We release one reference at the
* bottom of the function -- after delinking the vport. And we
* release the other at the completion of the unreg_vpi that get's
* initiated after we've disposed of all other resources associated
* with the port.
* Take early refcount for outstanding I/O requests we schedule during
* delete processing for unreg_vpi. Always keep this before
* scsi_remove_host() as we can no longer obtain a reference through
* scsi_host_get() after scsi_host_remove as shost is set to SHOST_DEL.
*/
if (!scsi_host_get(shost))
return VPORT_INVAL;
if (!scsi_host_get(shost)) {
scsi_host_put(shost);
return VPORT_INVAL;
}
lpfc_free_sysfs_attr(vport);
lpfc_debugfs_terminate(vport);
@@ -811,8 +800,9 @@ skip_logo:
if (!(vport->vpi_state & LPFC_VPI_REGISTERED) ||
lpfc_mbx_unreg_vpi(vport))
scsi_host_put(shost);
} else
} else {
scsi_host_put(shost);
}
lpfc_free_vpi(phba, vport->vpi);
vport->work_port_events = 0;

View File

@@ -3172,7 +3172,7 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
pr_err("%s could not find host no %u\n",
__func__, ev->u.set_flashnode.host_no);
err = -ENODEV;
goto put_host;
goto exit_set_fnode;
}
idx = ev->u.set_flashnode.flashnode_idx;

View File

@@ -2194,6 +2194,7 @@ unblock_reqs:
int ufshcd_hold(struct ufs_hba *hba, bool async)
{
int rc = 0;
bool flush_result;
unsigned long flags;
if (!ufshcd_is_clkgating_allowed(hba))
@@ -2226,7 +2227,9 @@ start:
}
spin_unlock_irqrestore(hba->host->host_lock, flags);
flush_work(&hba->clk_gating.ungate_work);
flush_result = flush_work(&hba->clk_gating.ungate_work);
if (hba->clk_gating.is_suspended && !flush_result)
goto out;
spin_lock_irqsave(hba->host->host_lock, flags);
if (hba->ufshcd_state == UFSHCD_STATE_OPERATIONAL)
goto start;
@@ -7582,7 +7585,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
*/
static irqreturn_t ufshcd_intr(int irq, void *__hba)
{
u32 intr_status, enabled_intr_status;
u32 intr_status, enabled_intr_status = 0;
irqreturn_t retval = IRQ_NONE;
struct ufs_hba *hba = __hba;
int retries = hba->nutrs;
@@ -7597,7 +7600,7 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
* read, make sure we handle them by checking the interrupt status
* again in a loop until we process all of the reqs before returning.
*/
do {
while (intr_status && retries--) {
enabled_intr_status =
intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
if (intr_status)
@@ -7606,7 +7609,7 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
retval |= ufshcd_sl_intr(hba, enabled_intr_status);
intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
} while (intr_status && --retries);
}
if (retval == IRQ_NONE) {
dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x\n",
@@ -7929,7 +7932,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
/* command completed already */
dev_err(hba->dev, "%s: cmd at tag %d successfully cleared from DB.\n",
__func__, tag);
goto out;
goto cleanup;
} else {
dev_err(hba->dev,
"%s: no response from device. tag = %d, err %d\n",
@@ -7963,6 +7966,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
goto out;
}
cleanup:
scsi_dma_unmap(cmd);
spin_lock_irqsave(host->host_lock, flags);

View File

@@ -254,7 +254,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz)
{
u32 div, mbrdiv;
div = DIV_ROUND_UP(spi->clk_rate, speed_hz);
/* Ensure spi->clk_rate is even */
div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz);
/*
* SPI framework set xfer->speed_hz to master->max_speed_hz if

View File

@@ -997,7 +997,14 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev)
struct tcmu_cmd_entry *entry = (void *) mb + CMDR_OFF + udev->cmdr_last_cleaned;
struct tcmu_cmd *cmd;
tcmu_flush_dcache_range(entry, sizeof(*entry));
/*
* Flush max. up to end of cmd ring since current entry might
* be a padding that is shorter than sizeof(*entry)
*/
size_t ring_left = head_to_end(udev->cmdr_last_cleaned,
udev->cmdr_size);
tcmu_flush_dcache_range(entry, ring_left < sizeof(*entry) ?
ring_left : sizeof(*entry));
if (tcmu_hdr_get_op(entry->hdr.len_op) == TCMU_OP_PAD) {
UPDATE_HEAD(udev->cmdr_last_cleaned,

View File

@@ -629,6 +629,24 @@ static const struct exar8250_board pbn_exar_XR17V35x = {
.exit = pci_xr17v35x_exit,
};
static const struct exar8250_board pbn_fastcom35x_2 = {
.num_ports = 2,
.setup = pci_xr17v35x_setup,
.exit = pci_xr17v35x_exit,
};
static const struct exar8250_board pbn_fastcom35x_4 = {
.num_ports = 4,
.setup = pci_xr17v35x_setup,
.exit = pci_xr17v35x_exit,
};
static const struct exar8250_board pbn_fastcom35x_8 = {
.num_ports = 8,
.setup = pci_xr17v35x_setup,
.exit = pci_xr17v35x_exit,
};
static const struct exar8250_board pbn_exar_XR17V4358 = {
.num_ports = 12,
.has_slave = true,
@@ -701,9 +719,9 @@ static const struct pci_device_id exar_pci_tbl[] = {
EXAR_DEVICE(EXAR, EXAR_XR17V358, pbn_exar_XR17V35x),
EXAR_DEVICE(EXAR, EXAR_XR17V4358, pbn_exar_XR17V4358),
EXAR_DEVICE(EXAR, EXAR_XR17V8358, pbn_exar_XR17V8358),
EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_exar_XR17V35x),
EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_exar_XR17V35x),
EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_exar_XR17V35x),
EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_fastcom35x_2),
EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_fastcom35x_4),
EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_fastcom35x_8),
EXAR_DEVICE(COMMTECH, COMMTECH_4222PCI335, pbn_fastcom335_2),
EXAR_DEVICE(COMMTECH, COMMTECH_4224PCI335, pbn_fastcom335_4),

View File

@@ -2264,6 +2264,10 @@ int serial8250_do_startup(struct uart_port *port)
if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) {
unsigned char iir1;
if (port->irqflags & IRQF_SHARED)
disable_irq_nosync(port->irq);
/*
* Test for UARTs that do not reassert THRE when the
* transmitter is idle and the interrupt has already
@@ -2273,8 +2277,6 @@ int serial8250_do_startup(struct uart_port *port)
* allow register changes to become visible.
*/
spin_lock_irqsave(&port->lock, flags);
if (up->port.irqflags & IRQF_SHARED)
disable_irq_nosync(port->irq);
wait_for_xmitr(up, UART_LSR_THRE);
serial_port_out_sync(port, UART_IER, UART_IER_THRI);
@@ -2286,9 +2288,10 @@ int serial8250_do_startup(struct uart_port *port)
iir = serial_port_in(port, UART_IIR);
serial_port_out(port, UART_IER, 0);
spin_unlock_irqrestore(&port->lock, flags);
if (port->irqflags & IRQF_SHARED)
enable_irq(port->irq);
spin_unlock_irqrestore(&port->lock, flags);
/*
* If the interrupt is not reasserted, or we otherwise

View File

@@ -2272,9 +2272,8 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
clk_disable(uap->clk);
}
static void __init
pl011_console_get_options(struct uart_amba_port *uap, int *baud,
int *parity, int *bits)
static void pl011_console_get_options(struct uart_amba_port *uap, int *baud,
int *parity, int *bits)
{
if (pl011_read(uap, REG_CR) & UART01x_CR_UARTEN) {
unsigned int lcr_h, ibrd, fbrd;
@@ -2307,7 +2306,7 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud,
}
}
static int __init pl011_console_setup(struct console *co, char *options)
static int pl011_console_setup(struct console *co, char *options)
{
struct uart_amba_port *uap;
int baud = 38400;
@@ -2375,8 +2374,8 @@ static int __init pl011_console_setup(struct console *co, char *options)
*
* Returns 0 if console matches; otherwise non-zero to use default matching
*/
static int __init pl011_console_match(struct console *co, char *name, int idx,
char *options)
static int pl011_console_match(struct console *co, char *name, int idx,
char *options)
{
unsigned char iotype;
resource_size_t addr;
@@ -2614,7 +2613,7 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap,
static int pl011_register_port(struct uart_amba_port *uap)
{
int ret;
int ret, i;
/* Ensure interrupts from this UART are masked and cleared */
pl011_write(0, uap, REG_IMSC);
@@ -2625,6 +2624,9 @@ static int pl011_register_port(struct uart_amba_port *uap)
if (ret < 0) {
dev_err(uap->port.dev,
"Failed to register AMBA-PL011 driver\n");
for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
if (amba_ports[i] == uap)
amba_ports[i] = NULL;
return ret;
}
}

View File

@@ -1733,9 +1733,11 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
ourport->tx_irq = ret + 1;
}
ret = platform_get_irq(platdev, 1);
if (ret > 0)
ourport->tx_irq = ret;
if (!s3c24xx_serial_has_interrupt_mask(port)) {
ret = platform_get_irq(platdev, 1);
if (ret > 0)
ourport->tx_irq = ret;
}
/*
* DMA is currently supported only on DT platforms, if DMA properties
* are specified.

View File

@@ -865,7 +865,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
unsigned int old_rows, old_row_size;
unsigned int new_cols, new_rows, new_row_size, new_screen_size;
unsigned int user;
unsigned short *newscreen;
unsigned short *oldscreen, *newscreen;
WARN_CONSOLE_UNLOCKED();
@@ -947,10 +947,11 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
if (new_scr_end > new_origin)
scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
new_scr_end - new_origin);
kfree(vc->vc_screenbuf);
oldscreen = vc->vc_screenbuf;
vc->vc_screenbuf = newscreen;
vc->vc_screenbuf_size = new_screen_size;
set_origin(vc);
kfree(oldscreen);
/* do part of a reset_terminal() */
vc->vc_top = 0;

View File

@@ -893,12 +893,22 @@ int vt_ioctl(struct tty_struct *tty,
console_lock();
vcp = vc_cons[i].d;
if (vcp) {
int ret;
int save_scan_lines = vcp->vc_scan_lines;
int save_font_height = vcp->vc_font.height;
if (v.v_vlin)
vcp->vc_scan_lines = v.v_vlin;
if (v.v_clin)
vcp->vc_font.height = v.v_clin;
vcp->vc_resize_user = 1;
vc_resize(vcp, v.v_cols, v.v_rows);
ret = vc_resize(vcp, v.v_cols, v.v_rows);
if (ret) {
vcp->vc_scan_lines = save_scan_lines;
vcp->vc_font.height = save_font_height;
console_unlock();
return ret;
}
}
console_unlock();
}

View File

@@ -390,21 +390,19 @@ static void acm_ctrl_irq(struct urb *urb)
if (current_size < expected_size) {
/* notification is transmitted fragmented, reassemble */
if (acm->nb_size < expected_size) {
if (acm->nb_size) {
kfree(acm->notification_buffer);
acm->nb_size = 0;
}
u8 *new_buffer;
alloc_size = roundup_pow_of_two(expected_size);
/*
* kmalloc ensures a valid notification_buffer after a
* use of kfree in case the previous allocation was too
* small. Final freeing is done on disconnect.
*/
acm->notification_buffer =
kmalloc(alloc_size, GFP_ATOMIC);
if (!acm->notification_buffer)
/* Final freeing is done on disconnect. */
new_buffer = krealloc(acm->notification_buffer,
alloc_size, GFP_ATOMIC);
if (!new_buffer) {
acm->nb_index = 0;
goto exit;
}
acm->notification_buffer = new_buffer;
acm->nb_size = alloc_size;
dr = (struct usb_cdc_notification *)acm->notification_buffer;
}
copy_size = min(current_size,

View File

@@ -299,6 +299,8 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x2386, 0x3119), .driver_info = USB_QUIRK_NO_LPM },
{ USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM },
/* DJI CineSSD */
{ USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },

View File

@@ -1202,12 +1202,15 @@ static int ncm_unwrap_ntb(struct gether *port,
int ndp_index;
unsigned dg_len, dg_len2;
unsigned ndp_len;
unsigned block_len;
struct sk_buff *skb2;
int ret = -EINVAL;
unsigned max_size = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize);
unsigned ntb_max = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize);
unsigned frame_max = le16_to_cpu(ecm_desc.wMaxSegmentSize);
const struct ndp_parser_opts *opts = ncm->parser_opts;
unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
int dgram_counter;
bool ndp_after_header;
/* dwSignature */
if (get_unaligned_le32(tmp) != opts->nth_sign) {
@@ -1226,25 +1229,37 @@ static int ncm_unwrap_ntb(struct gether *port,
}
tmp++; /* skip wSequence */
block_len = get_ncm(&tmp, opts->block_length);
/* (d)wBlockLength */
if (get_ncm(&tmp, opts->block_length) > max_size) {
if (block_len > ntb_max) {
INFO(port->func.config->cdev, "OUT size exceeded\n");
goto err;
}
ndp_index = get_ncm(&tmp, opts->ndp_index);
ndp_after_header = false;
/* Run through all the NDP's in the NTB */
do {
/* NCM 3.2 */
if (((ndp_index % 4) != 0) &&
(ndp_index < opts->nth_size)) {
/*
* NCM 3.2
* dwNdpIndex
*/
if (((ndp_index % 4) != 0) ||
(ndp_index < opts->nth_size) ||
(ndp_index > (block_len -
opts->ndp_size))) {
INFO(port->func.config->cdev, "Bad index: %#X\n",
ndp_index);
goto err;
}
if (ndp_index == opts->nth_size)
ndp_after_header = true;
/* walk through NDP */
/*
* walk through NDP
* dwSignature
*/
tmp = (void *)(skb->data + ndp_index);
if (get_unaligned_le32(tmp) != ncm->ndp_sign) {
INFO(port->func.config->cdev, "Wrong NDP SIGN\n");
@@ -1255,14 +1270,15 @@ static int ncm_unwrap_ntb(struct gether *port,
ndp_len = get_unaligned_le16(tmp++);
/*
* NCM 3.3.1
* wLength
* entry is 2 items
* item size is 16/32 bits, opts->dgram_item_len * 2 bytes
* minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry
* Each entry is a dgram index and a dgram length.
*/
if ((ndp_len < opts->ndp_size
+ 2 * 2 * (opts->dgram_item_len * 2))
|| (ndp_len % opts->ndplen_align != 0)) {
+ 2 * 2 * (opts->dgram_item_len * 2)) ||
(ndp_len % opts->ndplen_align != 0)) {
INFO(port->func.config->cdev, "Bad NDP length: %#X\n",
ndp_len);
goto err;
@@ -1279,8 +1295,21 @@ static int ncm_unwrap_ntb(struct gether *port,
do {
index = index2;
/* wDatagramIndex[0] */
if ((index < opts->nth_size) ||
(index > block_len - opts->dpe_size)) {
INFO(port->func.config->cdev,
"Bad index: %#X\n", index);
goto err;
}
dg_len = dg_len2;
if (dg_len < 14 + crc_len) { /* ethernet hdr + crc */
/*
* wDatagramLength[0]
* ethernet hdr + crc or larger than max frame size
*/
if ((dg_len < 14 + crc_len) ||
(dg_len > frame_max)) {
INFO(port->func.config->cdev,
"Bad dgram length: %#X\n", dg_len);
goto err;
@@ -1304,6 +1333,37 @@ static int ncm_unwrap_ntb(struct gether *port,
index2 = get_ncm(&tmp, opts->dgram_item_len);
dg_len2 = get_ncm(&tmp, opts->dgram_item_len);
if (index2 == 0 || dg_len2 == 0)
break;
/* wDatagramIndex[1] */
if (ndp_after_header) {
if (index2 < opts->nth_size + opts->ndp_size) {
INFO(port->func.config->cdev,
"Bad index: %#X\n", index2);
goto err;
}
} else {
if (index2 < opts->nth_size + opts->dpe_size) {
INFO(port->func.config->cdev,
"Bad index: %#X\n", index2);
goto err;
}
}
if (index2 > block_len - opts->dpe_size) {
INFO(port->func.config->cdev,
"Bad index: %#X\n", index2);
goto err;
}
/* wDatagramLength[1] */
if ((dg_len2 < 14 + crc_len) ||
(dg_len2 > frame_max)) {
INFO(port->func.config->cdev,
"Bad dgram length: %#X\n", dg_len);
goto err;
}
/*
* Copy the data into a new skb.
* This ensures the truesize is correct
@@ -1320,9 +1380,6 @@ static int ncm_unwrap_ntb(struct gether *port,
ndp_len -= 2 * (opts->dgram_item_len * 2);
dgram_counter++;
if (index2 == 0 || dg_len2 == 0)
break;
} while (ndp_len > 2 * (opts->dgram_item_len * 2));
} while (ndp_index);

View File

@@ -751,12 +751,13 @@ static int uasp_alloc_stream_res(struct f_uas *fu, struct uas_stream *stream)
goto err_sts;
return 0;
err_sts:
usb_ep_free_request(fu->ep_status, stream->req_status);
stream->req_status = NULL;
err_out:
usb_ep_free_request(fu->ep_out, stream->req_out);
stream->req_out = NULL;
err_out:
usb_ep_free_request(fu->ep_in, stream->req_in);
stream->req_in = NULL;
out:
return -ENOMEM;
}

View File

@@ -17,6 +17,7 @@
#define __U_F_H__
#include <linux/usb/gadget.h>
#include <linux/overflow.h>
/* Variable Length Array Macros **********************************************/
#define vla_group(groupname) size_t groupname##__next = 0
@@ -24,21 +25,36 @@
#define vla_item(groupname, type, name, n) \
size_t groupname##_##name##__offset = ({ \
size_t align_mask = __alignof__(type) - 1; \
size_t offset = (groupname##__next + align_mask) & ~align_mask;\
size_t size = (n) * sizeof(type); \
groupname##__next = offset + size; \
size_t offset = 0; \
if (groupname##__next != SIZE_MAX) { \
size_t align_mask = __alignof__(type) - 1; \
size_t size = array_size(n, sizeof(type)); \
offset = (groupname##__next + align_mask) & \
~align_mask; \
if (check_add_overflow(offset, size, \
&groupname##__next)) { \
groupname##__next = SIZE_MAX; \
offset = 0; \
} \
} \
offset; \
})
#define vla_item_with_sz(groupname, type, name, n) \
size_t groupname##_##name##__sz = (n) * sizeof(type); \
size_t groupname##_##name##__offset = ({ \
size_t align_mask = __alignof__(type) - 1; \
size_t offset = (groupname##__next + align_mask) & ~align_mask;\
size_t size = groupname##_##name##__sz; \
groupname##__next = offset + size; \
offset; \
size_t groupname##_##name##__sz = array_size(n, sizeof(type)); \
size_t groupname##_##name##__offset = ({ \
size_t offset = 0; \
if (groupname##__next != SIZE_MAX) { \
size_t align_mask = __alignof__(type) - 1; \
offset = (groupname##__next + align_mask) & \
~align_mask; \
if (check_add_overflow(offset, groupname##_##name##__sz,\
&groupname##__next)) { \
groupname##__next = SIZE_MAX; \
offset = 0; \
} \
} \
offset; \
})
#define vla_ptr(ptr, groupname, name) \

View File

@@ -166,9 +166,8 @@ skip_phy:
hcd->rsrc_len = resource_size(res);
irq = platform_get_irq(pdev, 0);
if (!irq) {
dev_err(&pdev->dev, "Failed to get IRQ\n");
err = -ENODEV;
if (irq < 0) {
err = irq;
goto fail_io;
}

View File

@@ -751,15 +751,6 @@ static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci,
{
u32 pls = status_reg & PORT_PLS_MASK;
/* resume state is a xHCI internal state.
* Do not report it to usb core, instead, pretend to be U3,
* thus usb core knows it's not ready for transfer
*/
if (pls == XDEV_RESUME) {
*status |= USB_SS_PORT_LS_U3;
return;
}
/* When the CAS bit is set then warm reset
* should be performed on port
*/
@@ -781,6 +772,16 @@ static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci,
*/
pls |= USB_PORT_STAT_CONNECTION;
} else {
/*
* Resume state is an xHCI internal state. Do not report it to
* usb core, instead, pretend to be U3, thus usb core knows
* it's not ready for transfer.
*/
if (pls == XDEV_RESUME) {
*status |= USB_SS_PORT_LS_U3;
return;
}
/*
* If CAS bit isn't set but the Port is already at
* Compliance Mode, fake a connection so the USB core

View File

@@ -439,7 +439,7 @@ static int lvs_rh_probe(struct usb_interface *intf,
USB_DT_SS_HUB_SIZE, USB_CTRL_GET_TIMEOUT);
if (ret < (USB_DT_HUB_NONVAR_SIZE + 2)) {
dev_err(&hdev->dev, "wrong root hub descriptor read %d\n", ret);
return ret;
return ret < 0 ? ret : -EINVAL;
}
/* submit urb to poll interrupt endpoint */

View File

@@ -760,7 +760,7 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
u8 swap8, fromkern = kernbuffer ? 1 : 0;
u16 swap16;
u32 swap32, flag = (length >> 28) & 1;
char buf[4];
u8 buf[4];
/* if neither kernbuffer not userbuffer are given, assume
* data in obuf

View File

@@ -496,7 +496,7 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
prepare_to_wait(&dev->waitq, &wait, TASK_INTERRUPTIBLE);
dev_dbg(&dev->interface->dev, "%s - submit %c\n", __func__,
dev->cntl_buffer[0]);
retval = usb_submit_urb(dev->cntl_urb, GFP_KERNEL);
retval = usb_submit_urb(dev->cntl_urb, GFP_ATOMIC);
if (retval >= 0)
timeout = schedule_timeout(YUREX_WRITE_TIMEOUT);
finish_wait(&dev->waitq, &wait);

View File

@@ -2347,7 +2347,7 @@ UNUSUAL_DEV( 0x357d, 0x7788, 0x0114, 0x0114,
"JMicron",
"USB to ATA/ATAPI Bridge",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA ),
US_FL_BROKEN_FUA | US_FL_IGNORE_UAS ),
/* Reported by Andrey Rahmatullin <wrar@altlinux.org> */
UNUSUAL_DEV( 0x4102, 0x1020, 0x0100, 0x0100,

View File

@@ -41,6 +41,13 @@
* and don't forget to CC: the USB development list <linux-usb@vger.kernel.org>
*/
/* Reported-by: Till Dörges <doerges@pre-sense.de> */
UNUSUAL_DEV(0x054c, 0x087d, 0x0000, 0x9999,
"Sony",
"PSZ-HA*",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_REPORT_OPCODES),
/* Reported-by: Julian Groß <julian.g@posteo.de> */
UNUSUAL_DEV(0x059f, 0x105f, 0x0000, 0x9999,
"LaCie",
@@ -156,6 +163,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA),
/* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999,
"PNY",
"Pro Elite SSD",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_ATA_1X),
/* Reported-by: Hans de Goede <hdegoede@redhat.com> */
UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999,
"VIA",

View File

@@ -2131,6 +2131,9 @@ static void updatescrollmode(struct display *p,
}
}
#define PITCH(w) (((w) + 7) >> 3)
#define CALC_FONTSZ(h, p, c) ((h) * (p) * (c)) /* size = height * pitch * charcount */
static int fbcon_resize(struct vc_data *vc, unsigned int width,
unsigned int height, unsigned int user)
{
@@ -2140,6 +2143,24 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
struct fb_var_screeninfo var = info->var;
int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
if (ops->p && ops->p->userfont && FNTSIZE(vc->vc_font.data)) {
int size;
int pitch = PITCH(vc->vc_font.width);
/*
* If user font, ensure that a possible change to user font
* height or width will not allow a font data out-of-bounds access.
* NOTE: must use original charcount in calculation as font
* charcount can change and cannot be used to determine the
* font data allocated size.
*/
if (pitch <= 0)
return -EINVAL;
size = CALC_FONTSZ(vc->vc_font.height, pitch, FNTCHARCNT(vc->vc_font.data));
if (size > FNTSIZE(vc->vc_font.data))
return -EINVAL;
}
virt_w = FBCON_SWAP(ops->rotate, width, height);
virt_h = FBCON_SWAP(ops->rotate, height, width);
virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
@@ -2602,7 +2623,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
int size;
int i, csum;
u8 *new_data, *data = font->data;
int pitch = (font->width+7) >> 3;
int pitch = PITCH(font->width);
/* Is there a reason why fbconsole couldn't handle any charcount >256?
* If not this check should be changed to charcount < 256 */
@@ -2618,7 +2639,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
if (fbcon_invalid_charcount(info, charcount))
return -EINVAL;
size = h * pitch * charcount;
size = CALC_FONTSZ(h, pitch, charcount);
new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);

View File

@@ -531,8 +531,11 @@ int dispc_runtime_get(void)
DSSDBG("dispc_runtime_get\n");
r = pm_runtime_get_sync(&dispc.pdev->dev);
WARN_ON(r < 0);
return r < 0 ? r : 0;
if (WARN_ON(r < 0)) {
pm_runtime_put_sync(&dispc.pdev->dev);
return r;
}
return 0;
}
EXPORT_SYMBOL(dispc_runtime_get);

View File

@@ -1148,8 +1148,11 @@ static int dsi_runtime_get(struct platform_device *dsidev)
DSSDBG("dsi_runtime_get\n");
r = pm_runtime_get_sync(&dsi->pdev->dev);
WARN_ON(r < 0);
return r < 0 ? r : 0;
if (WARN_ON(r < 0)) {
pm_runtime_put_sync(&dsi->pdev->dev);
return r;
}
return 0;
}
static void dsi_runtime_put(struct platform_device *dsidev)

View File

@@ -778,8 +778,11 @@ int dss_runtime_get(void)
DSSDBG("dss_runtime_get\n");
r = pm_runtime_get_sync(&dss.pdev->dev);
WARN_ON(r < 0);
return r < 0 ? r : 0;
if (WARN_ON(r < 0)) {
pm_runtime_put_sync(&dss.pdev->dev);
return r;
}
return 0;
}
void dss_runtime_put(void)

View File

@@ -50,9 +50,10 @@ static int hdmi_runtime_get(void)
DSSDBG("hdmi_runtime_get\n");
r = pm_runtime_get_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
if (r < 0)
if (WARN_ON(r < 0)) {
pm_runtime_put_sync(&hdmi.pdev->dev);
return r;
}
return 0;
}

View File

@@ -54,9 +54,10 @@ static int hdmi_runtime_get(void)
DSSDBG("hdmi_runtime_get\n");
r = pm_runtime_get_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
if (r < 0)
if (WARN_ON(r < 0)) {
pm_runtime_put_sync(&hdmi.pdev->dev);
return r;
}
return 0;
}

View File

@@ -402,8 +402,11 @@ static int venc_runtime_get(void)
DSSDBG("venc_runtime_get\n");
r = pm_runtime_get_sync(&venc.pdev->dev);
WARN_ON(r < 0);
return r < 0 ? r : 0;
if (WARN_ON(r < 0)) {
pm_runtime_put_sync(&venc.pdev->dev);
return r;
}
return 0;
}
static void venc_runtime_put(void)

View File

@@ -154,7 +154,7 @@ int get_evtchn_to_irq(unsigned evtchn)
/* Get info for IRQ */
struct irq_info *info_for_irq(unsigned irq)
{
return irq_get_handler_data(irq);
return irq_get_chip_data(irq);
}
/* Constructors for packed IRQ information. */
@@ -375,7 +375,7 @@ static void xen_irq_init(unsigned irq)
info->type = IRQT_UNBOUND;
info->refcnt = -1;
irq_set_handler_data(irq, info);
irq_set_chip_data(irq, info);
list_add_tail(&info->list, &xen_irq_list_head);
}
@@ -424,14 +424,14 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
static void xen_free_irq(unsigned irq)
{
struct irq_info *info = irq_get_handler_data(irq);
struct irq_info *info = irq_get_chip_data(irq);
if (WARN_ON(!info))
return;
list_del(&info->list);
irq_set_handler_data(irq, NULL);
irq_set_chip_data(irq, NULL);
WARN_ON(info->refcnt > 0);
@@ -601,7 +601,7 @@ EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
static void __unbind_from_irq(unsigned int irq)
{
int evtchn = evtchn_from_irq(irq);
struct irq_info *info = irq_get_handler_data(irq);
struct irq_info *info = irq_get_chip_data(irq);
if (info->refcnt > 0) {
info->refcnt--;
@@ -1105,7 +1105,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
void unbind_from_irqhandler(unsigned int irq, void *dev_id)
{
struct irq_info *info = irq_get_handler_data(irq);
struct irq_info *info = irq_get_chip_data(irq);
if (WARN_ON(!info))
return;
@@ -1139,7 +1139,7 @@ int evtchn_make_refcounted(unsigned int evtchn)
if (irq == -1)
return -ENOENT;
info = irq_get_handler_data(irq);
info = irq_get_chip_data(irq);
if (!info)
return -ENOENT;
@@ -1167,7 +1167,7 @@ int evtchn_get(unsigned int evtchn)
if (irq == -1)
goto done;
info = irq_get_handler_data(irq);
info = irq_get_chip_data(irq);
if (!info)
goto done;

View File

@@ -4344,6 +4344,7 @@ static void btrfs_cleanup_bg_io(struct btrfs_block_group_cache *cache)
cache->io_ctl.inode = NULL;
iput(inode);
}
ASSERT(cache->io_ctl.pages == NULL);
btrfs_put_block_group(cache);
}

View File

@@ -1169,7 +1169,6 @@ static int __btrfs_wait_cache_io(struct btrfs_root *root,
ret = update_cache_item(trans, root, inode, path, offset,
io_ctl->entries, io_ctl->bitmaps);
out:
io_ctl_free(io_ctl);
if (ret) {
invalidate_inode_pages2(inode->i_mapping);
BTRFS_I(inode)->generation = 0;
@@ -1334,6 +1333,7 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
* them out later
*/
io_ctl_drop_pages(io_ctl);
io_ctl_free(io_ctl);
unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
i_size_read(inode) - 1, &cached_state, GFP_NOFS);

View File

@@ -3311,11 +3311,13 @@ fail:
btrfs_free_path(path);
out_unlock:
mutex_unlock(&dir->log_mutex);
if (ret == -ENOSPC) {
if (err == -ENOSPC) {
btrfs_set_log_full_commit(root->fs_info, trans);
ret = 0;
} else if (ret < 0)
btrfs_abort_transaction(trans, ret);
err = 0;
} else if (err < 0 && err != -ENOENT) {
/* ENOENT can be returned if the entry hasn't been fsynced yet */
btrfs_abort_transaction(trans, err);
}
btrfs_end_log_trans(root);

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